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

15 篇文章 4 订阅

    利用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工程











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值