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

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

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

  1. class RegionInfo : INotifyPropertyChanged //地区信息
  2. {
  3. private string _province;//省
  4. private string _city;//市
  5. private string _area;//区
  6. public event PropertyChangedEventHandler PropertyChanged;
  7. public string Province
  8. {
  9. get { return _province; }
  10. set
  11. {
  12. _province = value;
  13. PropertyChanged(this, new PropertyChangedEventArgs("Province"));
  14. }
  15. }
  16. public string City
  17. {
  18. get { return _city; }
  19. set
  20. {
  21. _city = value;
  22. PropertyChanged(this, new PropertyChangedEventArgs("City"));
  23. }
  24. }
  25. public string Area
  26. {
  27. get { return _area; }
  28. set
  29. {
  30. _area = value;
  31. PropertyChanged(this, new PropertyChangedEventArgs("Area"));
  32. }
  33. }
  34. public RegionInfo(string province, string city, string area)//构造函数
  35. {
  36. _province = province;
  37. _city = city;
  38. _area = area;
  39. }
  40. }

二.编写DataGrid控件的XAML代码

  1. <!--AutoGenerateColumns="False"这句话告诉控件不自动生成列,是必要的,如果没有,控件会更具数据源自动生成列,这个在我们这种写法中看起来就有重复的两列数据-->
  2. <DataGrid x:Name="dataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top" Height="319" Width="302">
  3. <DataGrid.Columns>
  4. <!--省-->
  5. <DataGridTemplateColumn Header="省" Width="100">
  6. <!--显示模式-->
  7. <DataGridTemplateColumn.CellTemplate>
  8. <DataTemplate>
  9. <TextBlock Text="{Binding Path=Province ,Mode=TwoWay}"></TextBlock>
  10. </DataTemplate>
  11. </DataGridTemplateColumn.CellTemplate>
  12. <!--编辑模式-->
  13. <DataGridTemplateColumn.CellEditingTemplate>
  14. <DataTemplate>
  15. <ComboBox x:Name="ComboBoxProvince"  DropDownClosed="ProvinceDropDownClosed"  Loaded="ProvinceLoaded" Text="{Binding Path=Province ,Mode=TwoWay}" DisplayMemberPath="Province" ></ComboBox>
  16. </DataTemplate>
  17. </DataGridTemplateColumn.CellEditingTemplate>
  18. </DataGridTemplateColumn>
  19. <!--市-->
  20. <DataGridTemplateColumn Header="市" Width="100">
  21. <!--显示模式-->
  22. <DataGridTemplateColumn.CellTemplate>
  23. <DataTemplate>
  24. <TextBlock Text="{Binding Path=City ,Mode=TwoWay}"></TextBlock>
  25. </DataTemplate>
  26. </DataGridTemplateColumn.CellTemplate>
  27. <!--编辑模式-->
  28. <DataGridTemplateColumn.CellEditingTemplate>
  29. <DataTemplate>
  30. <ComboBox x:Name="ComboBoxCity" DropDownClosed="CityDropDownClosed" Loaded="CityLoaded" Text="{Binding Path=City,Mode=TwoWay}" DisplayMemberPath="City" ></ComboBox>
  31. </DataTemplate>
  32. </DataGridTemplateColumn.CellEditingTemplate>
  33. </DataGridTemplateColumn>
  34. <!--区-->
  35. <DataGridTemplateColumn Header="区" Width="100">
  36. <!--显示模式-->
  37. <DataGridTemplateColumn.CellTemplate>
  38. <DataTemplate>
  39. <TextBlock Text="{Binding Path=Area}"></TextBlock>
  40. </DataTemplate>
  41. </DataGridTemplateColumn.CellTemplate>
  42. <!--编辑模式-->
  43. <DataGridTemplateColumn.CellEditingTemplate>
  44. <DataTemplate>
  45. <ComboBox x:Name="ComboBoxArea"  DropDownClosed="AreaDropDownClosed" Loaded="AreaLoaded" Text="{Binding Path=Area}" DisplayMemberPath="Area" ></ComboBox>
  46. </DataTemplate>
  47. </DataGridTemplateColumn.CellEditingTemplate>
  48. </DataGridTemplateColumn>
  49. </DataGrid.Columns>
  50. </DataGrid>

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

对象声明

  1. ObservableCollection<RegionInfo> regionInfoList = new ObservableCollection<RegionInfo>();//DataGrid的数据源

对象添加

  1. //DataGrid初始绑定数据
  2. regionInfoList.Add(new RegionInfo("广东省", "深圳市", "罗湖区"));
  3. regionInfoList.Add(new RegionInfo("广东省", "深圳市", "南山区"));

对象绑定

  1. dataGrid.ItemsSource = regionInfoList;//绑定数据源

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

对象声明

  1. ObservableCollection<RegionInfo> regionInfoSelectList = new ObservableCollection<RegionInfo>();//用于DataGrid的模板列加载时提供选项

对象添加

  1. //三级联动数据项
  2. regionInfoSelectList.Add(new RegionInfo("广东省", "深圳市", "罗湖区"));
  3. regionInfoSelectList.Add(new RegionInfo("广东省", "深圳市", "南山区"));
  4. regionInfoSelectList.Add(new RegionInfo("广东省", "潮州市", "湘桥区"));
  5. regionInfoSelectList.Add(new RegionInfo("广东省", "潮州市", "枫溪区"));
  6. regionInfoSelectList.Add(new RegionInfo("湖北省", "武汉市", "江夏区"));
  7. regionInfoSelectList.Add(new RegionInfo("湖北省", "武汉市", "武昌区"));

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

  1. /// <summary>
  2. /// ProvinceLoaded 省份下拉列表框初始化,绑定数据源
  3. /// </summary>
  4. void ProvinceLoaded(object sender, RoutedEventArgs e)
  5. {
  6. ComboBox curComboBox = sender as ComboBox;
  7. //为下拉控件绑定数据源,并选择原选项为默认选项
  8. string text = curComboBox.Text;
  9. //去除重复项查找,跟数据库连接时可以让数据库来实现
  10. var query = regionInfoSelectList.GroupBy(p => p.Province).Select(p => new { Province = p.FirstOrDefault().Province });
  11. int itemcount = 0;
  12. curComboBox.SelectedIndex = itemcount;
  13. foreach (var item in query.ToList())
  14. {
  15. if (item.Province == text)
  16. {
  17. curComboBox.SelectedIndex = itemcount;
  18. break;
  19. }
  20. itemcount++;
  21. }
  22. curComboBox.ItemsSource = query;
  23. curComboBox.IsDropDownOpen = true;//获得焦点后下拉
  24. }
  25. /// <summary>
  26. /// CityLoaded 市下拉列表框初始化,绑定数据源
  27. /// </summary>
  28. void CityLoaded(object sender, RoutedEventArgs e)
  29. {
  30. //获得当前选中项的省份信息
  31. string province = (dataGrid.SelectedItem as RegionInfo).Province;
  32. //查找选中省份下的市作为数据源
  33. var query = (from l in regionInfoSelectList
  34. where (l.Province == province)
  35. group l by l.City into grouped
  36. select new { City = grouped.Key });
  37. ComboBox curComboBox = sender as ComboBox;
  38. //为下拉控件绑定数据源,并选择原选项为默认选项
  39. string text = curComboBox.Text;
  40. //去除重复项查找,跟数据库连接时可以让数据库来实现
  41. int itemcount = 0;
  42. curComboBox.SelectedIndex = itemcount;
  43. foreach (var item in query.ToList())
  44. {
  45. if (item.City == text)
  46. {
  47. curComboBox.SelectedIndex = itemcount;
  48. break;
  49. }
  50. itemcount++;
  51. }
  52. curComboBox.ItemsSource = query;
  53. curComboBox.IsDropDownOpen = true;//获得焦点后下拉
  54. }
  55. /// <summary>
  56. /// AreaLoaded 区下拉列表框初始化,绑定数据源
  57. /// </summary>
  58. void AreaLoaded(object sender, RoutedEventArgs e)
  59. {
  60. string province = (dataGrid.SelectedItem as RegionInfo).Province;
  61. string city = (dataGrid.SelectedItem as RegionInfo).City;
  62. //查找选中省份下的市作为数据源
  63. var query = (from l in regionInfoSelectList
  64. where (l.Province == province && l.City == city)
  65. group l by l.Area into grouped
  66. select new { Area = grouped.Key });
  67. ComboBox curComboBox = sender as ComboBox;
  68. //为下拉控件绑定数据源,并选择原选项为默认选项
  69. string text = curComboBox.Text;
  70. //去除重复项查找,跟数据库连接时可以让数据库来实现
  71. int itemcount = 0;
  72. curComboBox.SelectedIndex = itemcount;
  73. foreach (var item in query.ToList())
  74. {
  75. if (item.Area == text)
  76. {
  77. curComboBox.SelectedIndex = itemcount;
  78. break;
  79. }
  80. itemcount++;
  81. }
  82. curComboBox.ItemsSource = query;
  83. curComboBox.IsDropDownOpen = true;//获得焦点后下拉
  84. }

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

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

哦哦,更新代码分别写在

  1. /// <summary>
  2. /// CityDropDownClosed 市下拉列表框选择改变刷新
  3. /// </summary>
  4. private void CityDropDownClosed(object sender, EventArgs e)
  5. {
  6. }
  7. /// <summary>
  8. /// ProvinceDropDownClosed 省份下拉列表框选择改变刷新
  9. /// </summary>
  10. private void ProvinceDropDownClosed(object sender, EventArgs e)
  11. {
  12. }
  13. /// <summary>
  14. /// AreaDropDownClosed 区下拉列表框选择改变刷新
  15. /// </summary>
  16. private void AreaDropDownClosed(object sender, EventArgs e)
  17. {
  18. }

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

DEMO工程

C# WPF DataGrid控件实现三级联动的更多相关文章

  1. WPF DataGrid 控件的运用

    WPF DataGrid 控件的运用 运行环境:Window7 64bit,.NetFramework4.61,C# 6.0: 编者:乌龙哈里 2017-02-23 参考: King Cobra 博客 ...

  2. NPOI导出WPF DataGrid控件显示数据

    最近做个项目,需要导出DataGrid显示的数据,中间遇到了不少的坑,在此纪录一下,方便以后查看,也希望能给用到的人,一点帮助. 导出DataGrid显示的数据,并不是导出DataGrid的Items ...

  3. timer控件、三级联动

    timer控件: 实现时间日期自增长: using System; using System.Collections.Generic; using System.ComponentModel; usi ...

  4. 【2017-05-05】timer控件、三级联动、帐号激活权限设置

    一.Timer控件 Timer实际就是一个线程控件. 属性:Enabled    是否被启用 Interval     多长时间执行一次控件中的代码 事件: Tick     事件中放要执行的代码. ...

  5. timer控件、三级联动、帐号激活权限设置

    一.Timer控件 Timer实际就是一个线程控件. 属性:Enabled    是否被启用 Interval     多长时间执行一次控件中的代码 事件: Tick     事件中放要执行的代码. ...

  6. WPF DataGrid控件中某一列根据另一个文本列的值显示相应的模板控件

    之前做项目的时候需要实现这样一个功能.WPF DataGrid有两列,一列为"更新状态”列,一列为"值"列,如果"更新状态"列的值为“固定值更新”,则 ...

  7. WPF:获取DataGrid控件单元格DataGridCell

    转载:http://blog.csdn.net/jhqin/article/details/7645357 /* ------------------------------------------- ...

  8. wpf研究之道-datagrid控件(1)

    "想要说些什么 又不知从何说起",每当想要写一些关于wpf的文章,总是沉思良久,怕自己写不好.今天我想要说的是wpf中datagrid控件.我们先来看看它在整个类的层次结构:   ...

  9. wpf研究之道——datagrid控件分页

    这是我们的datagrid分页效果图,有上一页,下一页,可以跳到任何一页.当页码比较多的时候,只显示几页,其余用点点,界面实现如下: <!--分页--> <StackPanel Or ...

随机推荐

  1. 解决 Springboot中Interceptor拦截器中依赖注入失败

    问题: 在Springboot拦截器Interceptor中使用@Resource依赖注入时,发现运行的时候被注解的对象居然是null,没被注入进去 原配置为: @Configurationpubli ...

  2. Unity 过度光照贴图

    背景:开关窗帘过程,让环境在亮和暗之间过度 事先烘培出亮.暗两张Lighting map.然后代码实现,窗帘开关由动作实现,而代码中通过动作执行进度来过度两张Lighting map void OnA ...

  3. UVa11361 Investigating Div-Sum Property

    数位DP f[位数][自身模k余数][各位数字之和模k余数][当前位是否有上限]=方案数 k<10000,空间不够,如何优化? 不必优化,2^31以内,数字最多只有10位,各位数字之和最多为99 ...

  4. 标准C程序设计七---77

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  5. php的fastcgi_finish_request()函数

    php的fastcgi_finish_request()函数 功能: 此函数冲刷(flush)所有响应的数据给客户端并结束请求. 这使得客户端结束连接后,需要大量时间运行的任务能够继续运行. 返回值: ...

  6. poj 3281(构图+网络流)

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14144   Accepted: 6425 Descripti ...

  7. ping++微信渠道,第二次拉起不能进行支付返回订单号重复问题

    项目中用到了支付功能,采用的是ping++实现的,上线运行一年多都很正常,但是最近突然出现有买家反映说不能进行支付的情况 通过了解和沟通之后发现发现是重复拉起失败,然后我们对问题进行了排查. 测试过程 ...

  8. 深入了解Entity Framework框架及访问数据的几种方式

    一.前言 1.Entity Framework概要 Entity Framework是微软以ADO.NET为基础所发展出来的对象关系映射(O/R Mapping)解决方案.该框架曾经为.NET Fra ...

  9. Integration_Unit test coding standard

    Integration & Unit test coding standard 命名规则 好的命名规则,直接从命名就可以清楚的知道该测试方法测试的内容和目的,而不用额外的添加注释说明.对于MV ...

  10. [原创][FPGA]时钟分频之奇分频(5分频)

    0. 简介 有时在基本模块的设计中常常会使用到时钟分频,时钟的偶分频相对与奇分频比较简单,但是奇分频的理念想透彻后也是十分简单的,这里就把奇分频做一个记录. 1. 奇分频 其实现很简单,主要为使用两个 ...