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:
- 定义一个通用的键值实体类:
public class KeyValuePairItem<TKey, TValue> { public TKey Key { get; set; } public TValue Value { get; set; } }
- 在代码后台将
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();
- 在XAML中绑定对应的属性(比如显示自定义类的
Name属性):
<ComboBox x:Name="comboBox" DisplayMemberPath="Value.Name"/>
验证步骤
按照你的复现步骤,替换对应代码后运行应用,即可正常启动且无异常抛出。
内容的提问来源于stack exchange,提问作者kaismic
相关产品推荐
相关产品推荐

