WPF DataGrid中实现两个ComboBox联动绑定的需求
WPF DataGrid实现家族与家族类型ComboBox联动
1. 定义数据模型
先创建基础数据结构,同时实现INotifyPropertyChanged接口确保属性变化同步到UI:
using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; public class Family { public string Name { get; set; } public ObservableCollection<FamilyType> Types { get; set; } } public class FamilyType { public string TypeName { get; set; } } // DataGrid行对应的视图模型 public class DataRowViewModel : INotifyPropertyChanged { private Family _selectedFamily; public Family SelectedFamily { get => _selectedFamily; set { _selectedFamily = value; OnPropertyChanged(); // 切换家族时清空之前的类型选择(可选) SelectedType = null; } } private FamilyType _selectedType; public FamilyType SelectedType { get => _selectedType; set { _selectedType = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } // 主视图模型 public class MainViewModel : INotifyPropertyChanged { public ObservableCollection<Family> Families { get; set; } public ObservableCollection<DataRowViewModel> Rows { get; set; } public MainViewModel() { // 初始化示例数据 Families = new ObservableCollection<Family> { new Family { Name = "家族A", Types = new ObservableCollection<FamilyType> { new FamilyType { TypeName = "类型A1" }, new FamilyType { TypeName = "类型A2" } } }, new Family { Name = "家族B", Types = new ObservableCollection<FamilyType> { new FamilyType { TypeName = "类型B1" }, new FamilyType { TypeName = "类型B2" }, new FamilyType { TypeName = "类型B3" } } } }; // 初始化默认行数据 Rows = new ObservableCollection<DataRowViewModel> { new DataRowViewModel(), new DataRowViewModel() }; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 编写XAML布局
在Window中配置DataContext和DataGrid的联动列:
<Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp" Title="家族类型联动" Height="450" Width="800"> <Window.Resources> <!-- 空值转布尔值转换器:未选家族时禁用类型ComboBox --> <local:NullToBooleanConverter x:Key="NullToBooleanConverter"/> </Window.Resources> <Window.DataContext> <local:MainViewModel /> </Window.DataContext> <Grid> <DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False" CanUserAddRows="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <DataGrid.Columns> <!-- 家族选择列 --> <DataGridTemplateColumn Header="家族" Width="*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding DataContext.Families, RelativeSource={RelativeSource AncestorType=DataGrid}}" SelectedItem="{Binding SelectedFamily}" DisplayMemberPath="Name" Width="100%"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <!-- 家族类型选择列 --> <DataGridTemplateColumn Header="家族类型" Width="*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding SelectedFamily.Types}" SelectedItem="{Binding SelectedType}" DisplayMemberPath="TypeName" IsEnabled="{Binding SelectedFamily, Converter={StaticResource NullToBooleanConverter}}" Width="100%"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
3. 添加空值转换器
实现转换器控制类型选择框的启用状态:
using System; using System.Globalization; using System.Windows.Data; public class NullToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value != null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
核心逻辑说明
- 家族ComboBox通过
RelativeSource绑定全局的家族集合,确保所有行共用同一套家族选项 - 家族类型ComboBox的
ItemsSource直接绑定当前行选中的SelectedFamily.Types,选中不同家族时自动切换可选项 - 利用转换器确保只有选中家族后,类型选择框才可用,避免无效操作
内容的提问来源于stack exchange,提问作者Shehab Fekry
相关产品推荐
相关产品推荐

