Wpf Prism实现省市县ComboBox级联

本文介绍如何在WPF中实现省市县三级联动选择器,包括XAML布局配置及ViewModel逻辑处理,同时还演示了如何从XML文件加载数据并实现联动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        因一个小项目被要求用wpf实现,在这之前没使用过wpf,有些东西的实现方式不甚了解,只能一边摸索学习一边写代码。正好其中有一个省市县级联的需求,百度了一圈也没找到满足需要的,于是自己动手实现了下。在这里整理记录下实现过程,做个备忘。

先看效果

 view  xaml代码

        把省份的ItemsSource绑定ProvinceList,然后给城市的ItemsSource绑定到ElementName=省的SelectedItem上,同样县区的ItemsSource绑定到ElementName=市的SelectedItem上。

<Window x:Class="wpfdemo.Views.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:wpfdemo.Views"
        mc:Ignorable="d"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Height="300" Width="530" Title="demo" >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition Width="120"></ColumnDefinition>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition  Width="120"></ColumnDefinition>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition  Width="120"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Height="23"   HorizontalAlignment="Right"   Text="省:" VerticalAlignment="Top" />
            <ComboBox Grid.Column="1"  Height="23" Width="120" HorizontalAlignment="Left"  Name="Province" ItemsSource="{Binding ProvinceList}" Text="{Binding Province}" DisplayMemberPath="Name" VerticalAlignment="Top"   />
            <TextBlock Grid.Column="2"  Height="23" HorizontalAlignment="Right"  Text="市:" VerticalAlignment="Top" />
            <ComboBox Grid.Column="3"  Height="23" HorizontalAlignment="Left" Text="{Binding City}"  Name="City" ItemsSource="{Binding SelectedItem.Citys, ElementName=Province}"  DisplayMemberPath="Name" VerticalAlignment="Top" Width="120" />
            <TextBlock Grid.Column="4"  Height="23" HorizontalAlignment="Right"     Text="县区:" VerticalAlignment="Top" RenderTransformOrigin="3.5,0.662" />
            <ComboBox Grid.Column="5" Height="23"   HorizontalAlignment="Left" Text="{Binding County}" Name="County" ItemsSource="{Binding SelectedItem.Countys, ElementName=City}"  DisplayMemberPath="Name" VerticalAlignment="Top" Width="120" />
        </Grid>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="90"></ColumnDefinition>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition Width="350"/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0"  Height="30"  Width="100"  Command="{Binding GetData}" Grid.ColumnSpan="2" Margin="10,0,10,0" >获取数据</Button>
            <TextBox Grid.Column="2" Height="30" Text="{Binding txtData}" Width="350" Grid.ColumnSpan="2"></TextBox>
        </Grid>
    </Grid>
</Window>

viewmodel代码

        首先定义三个类,分别表示省、市、县三级。除了各自都有Name属性外,其中省中包含了市的list,市中包含了县的list。

/// <summary>
/// 县/区
/// </summary>
public class County
{
    public string Name { get; set; }
}
/// <summary>
/// 市
/// </summary>
public class City
{
    public string Name { get; set; }
    public List<County> Countys { get; set; }
}

/// <summary>
/// 省
/// </summary>
public class Province
{
    public string Name { get; set; }
    public List<City> Citys { get; set; }
}

        定义一个ProvinceList用于ItemsSource绑定,并通过InitData方法对ProvinceList进行赋值。这里省市县数据通过网上下载的一个xml充当数据源。


public List<Province> ProvinceList { set; get; }

public MainWindowViewModel()
{
     InitData();
}

/// <summary>
/// 初始化数据
/// </summary>
void InitData()
{
    XmlDocument doc = new XmlDocument();
    string path= ".\\ProvinceCode.xml";
    XmlNodeList cities, counties = null;

    doc.Load(path);

    XmlNode provinces = doc.SelectSingleNode("/root");

    ProvinceList = new List<Province>();
    Province p = new Province();
    City c = new City();
    County a = new County();

    foreach (XmlNode province in provinces.ChildNodes)
    {
        p = new Province();
        p.Name = province.Attributes["Name"].Value;

        path= string.Format("root/Province[@Name='{0}']/City", province.Attributes["Name"].Value);
        cities = doc.SelectNodes(path);

        p.Citys = new List<City>();
        foreach (XmlNode city in cities)
        {
            c = new City();
            c.Name = city.Attributes["Name"].Value;

            a = new County();
            path = string.Format("root/Province[@Name='{0}']/City[@Name='{1}']/County",
                                 province.Attributes["Name"].Value, city.Attributes["Name"].Value);

            c.Countys = new List<County>();
            counties = doc.SelectNodes(path);
            if (counties.Count == 0)
            {
                a.Name = "--请选择--";
                c.Countys.Add(a);
            }
            else
            {
                foreach (XmlNode county in counties)
                {
                    a = new County();
                    a.Name = county.Attributes["Name"].Value;
                    c.Countys.Add(a);
                }
            }
            p.Citys.Add(c);
        }
        ProvinceList.Add(p);
    }
}

        至此已实现了wpf的省市县的级联,接下来要取到想要的数据,需求还有要取到每个市的区号,也很简单。

private DelegateCommand _GetData = null;
public DelegateCommand GetData => _GetData ?? (_GetData = new DelegateCommand(GetData_Click));

void GetData_Click()
{
    if (County == "")
    {
        txtData = "请先选择省、市、县";
        return;
    }
    string targetParm = string.Format("root/Province/City[@Name='{0}']", City);//
    XmlDocument doc = new XmlDocument();
    string path= ".\\ProvinceCode.xml";
    doc.Load(path);

    XmlNode targetNode = doc.SelectSingleNode(targetParm);

    string areacode = targetNode.Attributes["areacode"].Value;

    txtData = string.Format("省份:{0},城市:{1},县/区:{2},区号:{3}", Province, City, County, areacode);
}

完整代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值