C#代码中ItemsSource绑定枚举类型失效的解决方法
问题原因
你在C#代码中直接实例化EnumBindingSource赋值给Binding.Source的写法是无效的:
- XAML解析器处理标记扩展时,会自动调用
MarkupExtension的ProvideValue方法,拿到扩展实际返回的枚举值集合作为绑定源 - 后台代码直接new出来的
EnumBindingSource只是一个普通的类实例,WPF绑定系统不会自动触发ProvideValue调用,绑定源始终是未执行取值逻辑的标记扩展对象,自然拿不到枚举数据。
修复方案
你用的是OneTime绑定模式,不需要响应后续数据源变更,有两种简单的实现方式:
方式1:手动调用ProvideValue拿到实际数据源再绑定
手动调用EnumBindingSource的ProvideValue方法,拿到生成好的枚举值集合再作为绑定源即可。由于你的枚举转字符串逻辑不依赖XAML上下文服务,参数传null即可:
public MyAdorner(UIElement adornedElement) : base(adornedElement) { ContextMenu contextMenu = new ContextMenu(); MenuItem color = new MenuItem() { Header = "Color" }; // 手动调用ProvideValue获取实际的枚举值列表 var enumBindingSource = new EnumBindingSource(typeof(MyColorEnum)) { ReturnStrings = true }; var enumValues = enumBindingSource.ProvideValue(null); color.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Source = enumValues, Mode = BindingMode.OneTime }); contextMenu.Items.Add(color); this.ContextMenu = contextMenu; }
方式2:直接赋值ItemsSource(更简洁)
因为是一次性加载枚举值,不需要绑定响应变更的话,可以直接把结果赋值给ItemsSource属性,省去创建Binding的步骤:
var enumBindingSource = new EnumBindingSource(typeof(MyColorEnum)) { ReturnStrings = true }; color.ItemsSource = enumBindingSource.ProvideValue(null) as IEnumerable;
补充说明
如果后续你需要让标记扩展在后台使用时兼容需要XAML服务的场景,可以通过IProvideValueTarget服务获取目标对象和属性,但你当前场景下枚举取值逻辑不依赖XAML上下文,直接传null调用ProvideValue完全可以正常工作。
内容的提问来源于stack exchange,提问作者flibbo
相关产品推荐
相关产品推荐

