C# WPF DataGrid控件实现三级联动

来源:转载

    利用DataGrid控件实现联动的功能,在数据库客户软件中是随处可见的,然而网上的资料却是少之又少,令人崩溃。

    本篇博文将介绍利用DataGrid控件模板定义的三个ComboBox实现“省、市、区”的三级联动。步骤如下:

    一.定义地域信息类(注意包含System.ComponentModel命名空间)

class RegionInfo : INotifyPropertyChanged //地区信息{ private string _province;//省 private string _city;//市 private string _area;//区 public event PropertyChangedEventHandler PropertyChanged; public string Province { get { return _province; } set { _province = value; PropertyChanged(this, new PropertyChangedEventArgs("Province")); } } public string City { get { return _city; } set { _city = value; PropertyChanged(this, new PropertyChangedEventArgs("City")); } } public string Area { get { return _area; } set { _area = value; PropertyChanged(this, new PropertyChangedEventArgs("Area")); } } public RegionInfo(string province, string city, string area)//构造函数 { _province = province; _city = city; _area = area; }}

    二.编写DataGrid控件的XAML代码

<!--AutoGenerateColumns="False"这句话告诉控件不自动生成列,是必要的,如果没有,控件会更具数据源自动生成列,这个在我们这种写法中看起来就有重复的两列数据--><DataGrid x:Name="dataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top" Height="319" Width="302">    <DataGrid.Columns>        <!--省-->        <DataGridTemplateColumn Header="省" Width="100">            <!--显示模式-->            <DataGridTemplateColumn.CellTemplate>                <DataTemplate>                    <TextBlock Text="{Binding Path=Province ,Mode=TwoWay}"></TextBlock>                </DataTemplate>            </DataGridTemplateColumn.CellTemplate>            <!--编辑模式-->            <DataGridTemplateColumn.CellEditingTemplate>                <DataTemplate>                    <ComboBox x:Name="ComboBoxProvince"  DropDownClosed="ProvinceDropDownClosed"  Loaded="ProvinceLoaded" Text="{Binding Path=Province ,Mode=TwoWay}" DisplayMemberPath="Province" ></ComboBox>                </DataTemplate>            </DataGridTemplateColumn.CellEditingTemplate>        </DataGridTemplateColumn>        <!--市-->        <DataGridTemplateColumn Header="市" Width="100">            <!--显示模式-->            <DataGridTemplateColumn.CellTemplate>                <DataTemplate>                    <TextBlock Text="{Binding Path=City ,Mode=TwoWay}"></TextBlock>                </DataTemplate>            </DataGridTemplateColumn.CellTemplate>            <!--编辑模式-->            <DataGridTemplateColumn.CellEditingTemplate>                <DataTemplate>                    <ComboBox x:Name="ComboBoxCity" DropDownClosed="CityDropDownClosed" Loaded="CityLoaded" Text="{Binding Path=City,Mode=TwoWay}" DisplayMemberPath="City" ></ComboBox>                </DataTemplate>            </DataGridTemplateColumn.CellEditingTemplate>        </DataGridTemplateColumn>        <!--区-->        <DataGridTemplateColumn Header="区" Width="100">            <!--显示模式-->            <DataGridTemplateColumn.CellTemplate>                <DataTemplate>                    <TextBlock Text="{Binding Path=Area}"></TextBlock>                </DataTemplate>            </DataGridTemplateColumn.CellTemplate>            <!--编辑模式-->            <DataGridTemplateColumn.CellEditingTemplate>                <DataTemplate>                    <ComboBox x:Name="ComboBoxArea"  DropDownClosed="AreaDropDownClosed" Loaded="AreaLoaded" Text="{Binding Path=Area}" DisplayMemberPath="Area" ></ComboBox>                </DataTemplate>            </DataGridTemplateColumn.CellEditingTemplate>        </DataGridTemplateColumn>    </DataGrid.Columns></DataGrid>

    三.为DataGrid控件准备数据源对象

    对象声明

ObservableCollection<RegionInfo> regionInfoList = new ObservableCollection<RegionInfo>();//DataGrid的数据源
    对象添加
//DataGrid初始绑定数据regionInfoList.Add(new RegionInfo("广东省", "深圳市", "罗湖区"));regionInfoList.Add(new RegionInfo("广东省", "深圳市", "南山区"));
    对象绑定
dataGrid.ItemsSource = regionInfoList;//绑定数据源

    四.为DataGrid控件的模板列加载时提供选项

    对象声明

ObservableCollection<RegionInfo> regionInfoSelectList = new ObservableCollection<RegionInfo>();//用于DataGrid的模板列加载时提供选项
    对象添加
//三级联动数据项regionInfoSelectList.Add(new RegionInfo("广东省", "深圳市", "罗湖区"));regionInfoSelectList.Add(new RegionInfo("广东省", "深圳市", "南山区"));regionInfoSelectList.Add(new RegionInfo("广东省", "潮州市", "湘桥区"));regionInfoSelectList.Add(new RegionInfo("广东省", "潮州市", "枫溪区"));regionInfoSelectList.Add(new RegionInfo("湖北省", "武汉市", "江夏区"));regionInfoSelectList.Add(new RegionInfo("湖北省", "武汉市", "武昌区"));

    五.在DataGrid模板列加载的时候实时更新其数据源并绑定到ComboBox的选项中

/// <summary>/// ProvinceLoaded 省份下拉列表框初始化,绑定数据源/// </summary>void ProvinceLoaded(object sender, RoutedEventArgs e){ ComboBox curComboBox = sender as ComboBox; //为下拉控件绑定数据源,并选择原选项为默认选项 string text = curComboBox.Text; //去除重复项查找,跟数据库连接时可以让数据库来实现 var query = regionInfoSelectList.GroupBy(p => p.Province).Select(p => new { Province = p.FirstOrDefault().Province }); int itemcount = 0; curComboBox.SelectedIndex = itemcount; foreach (var item in query.ToList()) { if (item.Province == text) { curComboBox.SelectedIndex = itemcount; break; } itemcount++; } curComboBox.ItemsSource = query; curComboBox.IsDropDownOpen = true;//获得焦点后下拉}/// <summary>/// CityLoaded 市下拉列表框初始化,绑定数据源/// </summary>void CityLoaded(object sender, RoutedEventArgs e){ //获得当前选中项的省份信息 string province = (dataGrid.SelectedItem as RegionInfo).Province; //查找选中省份下的市作为数据源 var query = (from l in regionInfoSelectList where (l.Province == province) group l by l.City into grouped select new { City = grouped.Key }); ComboBox curComboBox = sender as ComboBox; //为下拉控件绑定数据源,并选择原选项为默认选项 string text = curComboBox.Text; //去除重复项查找,跟数据库连接时可以让数据库来实现 int itemcount = 0; curComboBox.SelectedIndex = itemcount; foreach (var item in query.ToList()) { if (item.City == text) { curComboBox.SelectedIndex = itemcount; break; } itemcount++; } curComboBox.ItemsSource = query; curComboBox.IsDropDownOpen = true;//获得焦点后下拉}/// <summary>/// AreaLoaded 区下拉列表框初始化,绑定数据源/// </summary>void AreaLoaded(object sender, RoutedEventArgs e){ string province = (dataGrid.SelectedItem as RegionInfo).Province; string city = (dataGrid.SelectedItem as RegionInfo).City; //查找选中省份下的市作为数据源 var query = (from l in regionInfoSelectList where (l.Province == province && l.City == city) group l by l.Area into grouped select new { Area = grouped.Key }); ComboBox curComboBox = sender as ComboBox; //为下拉控件绑定数据源,并选择原选项为默认选项 string text = curComboBox.Text; //去除重复项查找,跟数据库连接时可以让数据库来实现 int itemcount = 0; curComboBox.SelectedIndex = itemcount; foreach (var item in query.ToList()) { if (item.Area == text) { curComboBox.SelectedIndex = itemcount; break; } itemcount++; } curComboBox.ItemsSource = query; curComboBox.IsDropDownOpen = true;//获得焦点后下拉}

    做到这一步基本上算是做完了,但是编译运行后会发现在选择省或者市的时候,后面的选项并没有做相应的改变,这是上一篇文章 C# WPF DataGrid控件同行编辑的实时更新问题 所述的问题,所以还需最后一步

    六.参考 C# WPF DataGrid控件同行编辑的实时更新问题 解决更新问题(懒得再写一遍了哈哈)

    哦哦,更新代码分别写在

/// <summary>/// CityDropDownClosed 市下拉列表框选择改变刷新/// </summary>private void CityDropDownClosed(object sender, EventArgs e){}/// <summary>/// ProvinceDropDownClosed 省份下拉列表框选择改变刷新/// </summary>private void ProvinceDropDownClosed(object sender, EventArgs e){}/// <summary>/// AreaDropDownClosed 区下拉列表框选择改变刷新/// </summary>private void AreaDropDownClosed(object sender, EventArgs e){}

这三个函数中。如果还想再只能点,在省下拉列表选择后,市下拉列表下拉。市下拉列表选择后,区下拉列表下拉,则可以参考 C# WPF 模拟键盘输入与UI控件进行交互 这篇文章,然后在上面提到的省、市两个下拉列表框中模拟键盘按下“TAD”键即可。

    DEMO工程













分享给朋友:
您可能感兴趣的文章:
随机阅读: