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

如何将DataGridComboBoxColumn.ItemsSource绑定到DataGrid行的不同派生类Enum集合

解决方法

1. 重构基类与派生类,实现枚举的抽象暴露

首先得给基类加两个抽象属性,让每个派生类自行返回对应的枚举选项和选中的命令,同时补全INotifyPropertyChanged的实现——你原来的基类只继承了接口但没实现通知方法,这会导致绑定不更新:

修正后的基类Base

public abstract class Base : INotifyPropertyChanged
{
    public abstract event EventHandler<DataEventArgs> dataUpdate;
    public string? addr { get; set; }
    public string? name { get; set; }
    public string? port { get; set; }

    // 让派生类返回自己的枚举列表
    public abstract IEnumerable<object> CommandOptions { get; }
    // 保存当前选中的命令,派生类要转成自己的枚举类型
    public abstract object SelectedCommand { get; set; }

    // 实现属性变更通知
    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

调整Derived类

public class Derived : Base
{
    public override event EventHandler<DataEventArgs>? dataUpdate;

    public enum CMDS
    {
        CMD1 = 0x024F032E,
        CMD2 = 0x0253032A,
        CMD3 = 0x0252032B,
        CMD4 = 0x0250032D,
        CMD5 = 0x0270030D,
        CMD6 = 0x02570326
    }

    private CMDS _selectedCmd;
    // 实现基类的选中命令属性,只接受自己的枚举类型
    public override object SelectedCommand
    {
        get => _selectedCmd;
        set
        {
            if (value is CMDS cmd)
            {
                _selectedCmd = cmd;
                OnPropertyChanged();
            }
        }
    }

    // 返回当前类的所有枚举值
    public override IEnumerable<object> CommandOptions => Enum.GetValues(typeof(CMDS)).Cast<object>();
}

调整Derived2类

public class Derived2 : Base
{
    public override event EventHandler<DataEventArgs>? dataUpdate;

    public enum CMDS
    {
        CMD1 = 0x024F332E,
        CMD2 = 0x0224F32A,
        CMD3 = 0x0252032B
    }

    private CMDS _selectedCmd;
    public override object SelectedCommand
    {
        get => _selectedCmd;
        set
        {
            if (value is CMDS cmd)
            {
                _selectedCmd = cmd;
                OnPropertyChanged();
            }
        }
    }

    public override IEnumerable<object> CommandOptions => Enum.GetValues(typeof(CMDS)).Cast<object>();
}

2. 用DataGridTemplateColumn替换DataGridComboBoxColumn

DataGridComboBoxColumn的ItemsSource只能绑定到列级上下文,没法拿到当前行的派生类实例,所以必须换成DataGridTemplateColumn,里面嵌套ComboBox,这样就能直接绑定到每行的数据:

修改后的XAML

<DataGrid ItemsSource="{Binding Collection}" AutoGenerateColumns="False" CanUserAddRows="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding name}"/>
        <DataGridTextColumn Header="IP Address" Binding="{Binding addr}"/>
        <DataGridTextColumn Header="Port" Binding="{Binding port}"/>
        <!-- 动态加载对应派生类枚举的ComboBox列 -->
        <DataGridTemplateColumn Header="Command">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding CommandOptions}"
                              SelectedItem="{Binding SelectedCommand, Mode=TwoWay}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding CommandOptions}"
                              SelectedItem="{Binding SelectedCommand, Mode=TwoWay}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

为什么原来的方法行不通?

  • 你之前在基类加CmdsList的问题:基类不知道具体派生类的枚举,没法动态返回对应的值,而且绑定到Window的DataContext只能拿到基类的属性,区分不了每行的派生类型。
  • DataGridComboBoxColumn的局限性:它的ItemsSource是列共享的,没法针对每行加载不同的选项,必须用模板列才能实现行级的动态绑定。

内容的提问来源于stack exchange,提问作者gwiz_kid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:14:58