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

C# WPF中如何将RadGridView列绑定到字典值?

解决RadGridView绑定字典值生成动态列的问题

你遇到的核心问题是:WPF绑定系统无法直接将MyDictionary["键名"]这种索引器语法作为属性路径识别;而共享CurrentlyFormingColumnName属性的方式会导致所有列复用同一个属性值,最终显示最后一次设置的键对应的数据。

以下是三种可行的解决方案:

方案1:使用绑定转换器

创建一个转换器,接收当前行的字典对象和目标键,返回对应的值,避免列之间的干扰。

转换器代码

public class DictionaryValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Dictionary<string, decimal> dict && parameter is string key && dict.ContainsKey(key))
        {
            return dict[key];
        }
        return 0m; // 无对应键时返回默认值
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException(); // 只读列无需反向转换
    }
}

生成列的代码

var dictConverter = new DictionaryValueConverter();
var myKeys = ViewModel.MyDictionaryKeys;

foreach (var name in myKeys)
{
    MyRadGridView.Columns.Add(new GridViewDataColumn()
    {
        Header = name,
        IsReadOnly = true,
        DataMemberBinding = new Binding("MyDictionary")
        {
            Converter = dictConverter,
            ConverterParameter = name
        }
    });
}

这个方案无需修改原有ViewModel结构,通过转换器参数传递不同键值,确保每列获取对应的数据。

方案2:为行数据创建动态属性(ExpandoObject)

将原行数据包装为动态对象,把字典的每个键转为动态属性,直接通过属性名绑定。

转换行数据的代码

var originalRows = ViewModel.ResultRows;
var dynamicRows = new ObservableCollection<ExpandoObject>();

foreach (var row in originalRows)
{
    var expandoDict = (IDictionary<string, object>)new ExpandoObject();
    // 若原ViewModel有其他需要绑定的属性,可在此添加
    // expandoDict["Id"] = row.Id;
    
    foreach (var kvp in row.MyDictionary)
    {
        expandoDict[kvp.Key] = kvp.Value;
    }
    dynamicRows.Add((ExpandoObject)expandoDict);
}

// 将GridView的数据源切换为动态对象集合
MyRadGridView.ItemsSource = dynamicRows;

生成列的代码

var myKeys = ViewModel.MyDictionaryKeys;
foreach (var name in myKeys)
{
    MyRadGridView.Columns.Add(new GridViewDataColumn()
    {
        Header = name,
        IsReadOnly = true,
        DataMemberBinding = new Binding(name)
    });
}

此方案适合无需保留原ViewModel结构的场景,绑定语法更简洁。

方案3:为ViewModel添加索引器属性

在MyResultRowsViewModels中添加索引器,让绑定系统可以通过索引器语法访问字典值。

修改ViewModel代码

public class MyResultRowsViewModels
{
    public Dictionary<string, decimal> MyDictionary { get; set; }

    // 添加索引器
    public decimal this[string key]
    {
        get
        {
            return MyDictionary.TryGetValue(key, out var value) ? value : 0m;
        }
    }
}

生成列的代码

var myKeys = ViewModel.MyDictionaryKeys;
foreach (var name in myKeys)
{
    MyRadGridView.Columns.Add(new GridViewDataColumn()
    {
        Header = name,
        IsReadOnly = true,
        DataMemberBinding = new Binding($"[{name}]")
    });
}

这个方案仅需修改原ViewModel,语法简洁,绑定系统原生支持索引器路径。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:15:19