WPF retrieve data from ASP.NET Core WebAPI according to SelectedItem changed

//WebAPI
//D:\C\WebApplication6\Controllers\CountyController.cs
using CsvHelper;
using CsvHelper.Configuration;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Globalization;

namespace WebApplication6.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CountyController : ControllerBase
    {
        private static List<CountyModel> countyList = new List<CountyModel>();
        private static List<string> stateList = new List<string>();
        static CountyController()
        {
            string csvFile = @"uscounties.csv";
            ReadDataFromCSV(csvFile);
        }
        public CountyController()
        {
           
        }

        private static void ReadDataFromCSV(string csvFile)
        {
            if (!System.IO.File.Exists(csvFile))
            {
                return;
            }

            string csvStr = System.IO.File.ReadAllText(csvFile);
            using (StringReader sr = new StringReader(csvStr))
            {
                var config = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    PrepareHeaderForMatch = args => args.Header.ToLower(),
                    MissingFieldFound = null,
                    HeaderValidated = null
                };

                using(var reader=new CsvReader(sr,config))
                {
                    countyList = reader.GetRecords<CountyModel>().ToList();
                    stateList = countyList.Select(x => x.State_Name).Distinct().OrderBy(x=>x).ToList();
                };
            }
        }

        [HttpGet("GetCountyList/{stateName}")]
        public List<CountyModel> GetCountyList(string stateName)
        {
            return countyList.Where(x => string.Equals(x.State_Name, stateName, StringComparison.InvariantCultureIgnoreCase)).OrderBy(x=>x.County).ToList();
        }

        [HttpGet("GetStateList")]
        public List<string> GetStateList()
        {
            return stateList;
        }
    }

    public class CountyModel
    {
        public string County { get; set; }
        public string County_Ascii { get; set; }
        public string County_Full { get; set; }
        public string County_Fips { get; set; }
        public string State_Name { get; set; }
        public double Lat { get; set; }
        public string Lng { get; set; }
        public long Population { get; set; }
    }
}


//D:\C\WebApplication6\Program.cs

namespace WebApplication6
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            builder.WebHost.UseKestrel(x =>
            {
                x.ListenLocalhost(5000);
                x.ListenLocalhost(5001, o =>
                {
                    o.UseHttps();
                });
            });

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
            builder.Services.AddOpenApi();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.MapOpenApi();
            }

            //app.UseHttpsRedirection();

            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }
    }
}

 

 

 

//WPF
//D:\C\WpfApp15\MainWindow.xaml
<Window x:Class="WpfApp15.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp15"
        mc:Ignorable="d"
        Title="{Binding MainTitle}" WindowState="Maximized">
    <Window.DataContext>
        <local:MainVM/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>

        <ListBox Grid.Column="0"
                 BorderBrush="LightBlue"
                 BorderThickness="2"
                 Margin="5"
                 ItemsSource="{Binding StateCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 SelectedItem="{Binding SelectedState,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="FontSize" Value="30"/>
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Foreground" Value="Red"/>
                            <Setter Property="FontWeight" Value="ExtraBold"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontWeight" Value="ExtraBold"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

        <DataGrid Grid.Column="1"
                  BorderBrush="LightBlue"
                  BorderThickness="2"
                  Margin="5"
                  ItemsSource="{Binding CountyCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  AutoGenerateColumns="True"
                  CanUserReorderColumns="False"
                  CanUserAddRows="False"
                  IsReadOnly="True"
                  UseLayoutRounding="True"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling"
                  VirtualizingPanel.CacheLengthUnit="Item"
                  VirtualizingPanel.CacheLength="5,5"
                  ScrollViewer.CanContentScroll="True"
                  ScrollViewer.IsDeferredScrollingEnabled="True">
            <DataGrid.ItemContainerStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="FontSize" Value="30"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontWeight" Value="ExtraBold"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.ItemContainerStyle>
            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Foreground" Value="Red"/>
                            <Setter Property="Background" Value="White"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontWeight" Value="ExtraBold"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.CellStyle>
        </DataGrid>
    </Grid>
</Window>


//D:\C\WpfApp15\MainWindow.xaml.cs
using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp15
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        string stateUrl = "https://localhost:5001/api/county/getstatelist";
        string countyUrl = "https://localhost:5001/api/county/getcountylist/";
        static HttpClient client = new HttpClient()
        {
            Timeout = TimeSpan.FromHours(1)
        };

        public MainVM()
        {
            if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                _ = LoadStateListAsync();
            }
        }

        private async Task LoadStateListAsync()
        {
            try
            {
                string stateStr = await client.GetStringAsync(stateUrl);
                if (!string.IsNullOrWhiteSpace(stateStr))
                {
                    var stateList = JsonConvert.DeserializeObject<List<string>>(stateStr);
                    if (stateList != null && stateList.Any())
                    {
                        StateCollection = new ObservableCollection<string>(stateList);
                        SelectedState = StateCollection.FirstOrDefault();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex?.Message);
            }
        }

        private ObservableCollection<string> stateCollection;
        public ObservableCollection<string> StateCollection
        {
            get
            {
                return stateCollection;
            }
            set
            {
                if (value != stateCollection)
                {
                    stateCollection = value;
                    OnPropertyChanged();
                }
            }
        }

        private string selectedState;
        public string SelectedState
        {
            get
            {
                return selectedState;
            }
            set
            {
                if (value != selectedState)
                {
                    selectedState = value;
                    OnPropertyChanged();
                    OnSelectedStateChanged();
                }
            }
        }

        private async Task OnSelectedStateChanged()
        {
            string countyStr = await client.GetStringAsync($"{countyUrl}{SelectedState}");
            var countyList = JsonConvert.DeserializeObject<List<CountyModel>>(countyStr);
            if(countyList!=null && countyList.Any())
            {
                CountyCollection = new ObservableCollection<CountyModel>(countyList);
            }
        }

        private ObservableCollection<CountyModel> countyCollection;
        public ObservableCollection<CountyModel> CountyCollection
        {
            get
            {
                return countyCollection;
            }
            set
            {
                if (value != countyCollection)
                {
                    countyCollection = value;
                    OnPropertyChanged();
                }
            }
        }



        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "")
        {
            var handler = Volatile.Read(ref PropertyChanged);
            if (handler == null)
            {
                return;
            }
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }

    public class CountyModel
    {
        public string County { get; set; }
        public string County_Ascii { get; set; }
        public string County_Full { get; set; }
        public string County_Fips { get; set; }
        public string State_Name { get; set; }
        public double Lat { get; set; }
        public string Lng { get; set; }
        public long Population { get; set; }
    }
}

 

 

 

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

image

 

image

 

posted @ 2026-09-12 21:39  FredGrit  阅读(5)  评论(0)    收藏  举报