您的位置:首页 > 编程语言 > C#

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

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

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

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

[csharp] view plain copy

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代码

[csharp] view plain copy

<!--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控件准备数据源对象

对象声明

[csharp] view plain copy

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

对象添加

[csharp] view plain copy

//DataGrid初始绑定数据

regionInfoList.Add(new RegionInfo("广东省", "深圳市", "罗湖区"));

regionInfoList.Add(new RegionInfo("广东省", "深圳市", "南山区"));

对象绑定

[csharp] view plain copy

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

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

对象声明

[csharp] view plain copy

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

对象添加

[csharp] view plain copy

//三级联动数据项

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的选项中

[csharp] view plain copy

/// <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控件同行编辑的实时更新问题 解决更新问题(懒得再写一遍了哈哈)

哦哦,更新代码分别写在

[csharp] view plain copy

/// <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工程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: