You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:15:40