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

WPF DataGrid不同行绑定不同列表的实现问询

实现WPF DataGrid行级动态切换ComboBox数据源的方案

核心思路

DataGridComboBoxColumn的ItemsSource是全局绑定的,无法实现行级动态切换。解决办法是改用DataGridTemplateColumn嵌入ComboBox,通过每行数据对象的属性动态返回对应数据源,同时实现属性变更通知让UI自动更新。

步骤1:修改ProfileItem类

让类实现INotifyPropertyChanged接口,添加一个根据IsRound动态返回数据源的属性,并在IsRound变化时通知UI更新:

using System.ComponentModel;
using System.Runtime.CompilerServices;

internal class ProfileItem : INotifyPropertyChanged
{
    public string ProfileName { get; set; }
    
    private bool _isRound;
    public bool IsRound
    {
        get => _isRound;
        set
        {
            if (_isRound != value)
            {
                _isRound = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(AvailableProfileTypes)); // 切换时触发数据源更新
            }
        }
    }
    
    public string ProfileType { get; set; }
    public Element ProfileElement { get; set; }

    // 全局共享的类型列表(也可通过构造函数传入,根据项目结构调整)
    public static List<string> RoundProfileTypeNames { get; set; }
    public static List<string> RectProfileTypeNames { get; set; }

    // 动态返回当前行对应的数据源
    public IEnumerable<string> AvailableProfileTypes
    {
        get => IsRound ? RoundProfileTypeNames : RectProfileTypeNames;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:修改XAML布局

替换原DataGridComboBoxColumn为DataGridTemplateColumn,让每行的ComboBox绑定到AvailableProfileTypes:

<DataGrid Name="profilePropsGrid" Width="500" CanUserReorderColumns="False" HorizontalAlignment="Center" CanUserAddRows="False" VerticalAlignment="Top" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Profile Name" Width="*" Binding="{Binding ProfileName}" IsReadOnly="true" />
        <DataGridTemplateColumn Header="Is Rounded Profile?" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsRound, Mode=TwoWay}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Width="100" Header="Profile Type">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding AvailableProfileTypes}" 
                              SelectedItem="{Binding ProfileType, Mode=TwoWay}"
                              DisplayMemberPath="." />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <!-- 编辑模式模板(与显示模板一致即可) -->
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding AvailableProfileTypes}" 
                              SelectedItem="{Binding ProfileType, Mode=TwoWay}"
                              DisplayMemberPath="." />
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

步骤3:调整后台代码

将全局类型列表传递给ProfileItem,并简化IsRound的赋值逻辑:

// 先初始化全局类型列表(假设你已经完成这一步)
// roundProfileTypeNames = new List<string> { ... };
// rectProfileTypeNames = new List<string> { ... };

// 传递给ProfileItem的静态属性
ProfileItem.RoundProfileTypeNames = roundProfileTypeNames;
ProfileItem.RectProfileTypeNames = rectProfileTypeNames;

bridgeProfileList = new List<ProfileItem>();

foreach (Element elem in framingPipeTypesCol)
{
    ProfileItem ep = new ProfileItem()
    {
        ProfileName = elem.Name,
        ProfileElement = elem
    };
    IList<Parameter> pipe_shape_circle = elem.GetParameters("Pipe Shape_Circle");
    if (pipe_shape_circle.Count > 0)
    {
        ep.IsRound = pipe_shape_circle[0].AsInteger() == 1;
    }
    bridgeProfileList.Add(ep);
}
profilePropsGrid.ItemsSource = bridgeProfileList;
// 移除原有的ProfileType.ItemsSource赋值,现在由每行自己管理数据源

关键说明

  • 放弃DataGridComboBoxColumn:该列的ItemsSource是全局配置,无法实现行级动态切换,改用模板列可以绑定到每行数据对象的属性。
  • 属性变更通知:INotifyPropertyChanged确保当IsRound勾选状态变化时,AvailableProfileTypes的变更能及时通知UI,自动切换ComboBox的数据源。
  • 移除事件处理:原CheckBox的Checked/Unchecked事件不再需要,TwoWay绑定会自动同步IsRound的值,触发后续的数据源更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:17:49