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

WinUI3中ComboBox绑定Dictionary<TKey,自定义类>抛出InvalidOperationException异常

WinUI3 ComboBox绑定Dictionary<TKey,自定义类>抛出异常的解决方案

问题原因

WinUI3基于WinRT框架,要求绑定到ItemsSource的集合元素必须是WinRT投影类型(即能被WinRT识别并转换的类型)。当绑定Dictionary<TKey,TValue>时,实际传递的是KeyValuePair<TKey,TValue>类型的集合:

  • 当TValue是int这类基本值类型时,WinRT有对应的投影实现,所以可以正常绑定;
  • 当TValue是自定义类时,自定义类默认不是WinRT投影类型,且KeyValuePair本身也不具备WinRT兼容性,因此触发System.InvalidOperationException异常,提示Target type is not a projected type。

解决方案

方案1:将自定义类标记为WinRT投影类型

给自定义类添加[WebHostHidden]特性(需要引用Windows.Foundation.Metadata命名空间),同时确保类和属性都是public访问级别:

using Windows.Foundation.Metadata;

[WebHostHidden]
public class Sample
{
    public string Name { get; set; }
    public int Age { get; set; }
}

添加特性后,WinRT会将该类识别为可投影类型,此时直接绑定Dictionary<string,Sample>即可正常运行。

方案2:转换Dictionary为兼容的集合类型(推荐)

如果不想修改自定义类的特性,或者自定义类有复杂依赖不适合标记为投影类型,可以将Dictionary转换为包含键值对的自定义实体集合,再绑定到ItemsSource:

  1. 定义一个通用的键值实体类:
public class KeyValuePairItem<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}
  1. 在代码后台将Dictionary转换为该实体的集合:
// 假设你的原始Dictionary
var sampleDict = new Dictionary<string, Sample>
{
    { "Item1", new Sample { Name = "示例1", Age = 25 } },
    { "Item2", new Sample { Name = "示例2", Age = 30 } }
};

// 转换为兼容的集合
comboBox.ItemsSource = sampleDict.Select(kv => new KeyValuePairItem<string, Sample>
{
    Key = kv.Key,
    Value = kv.Value
}).ToList();
  1. 在XAML中绑定对应的属性(比如显示自定义类的Name属性):
<ComboBox x:Name="comboBox" DisplayMemberPath="Value.Name"/>

验证步骤

按照你的复现步骤,替换对应代码后运行应用,即可正常启动且无异常抛出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:42:37