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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:09:20