XAML 使用静态枚举键绑定集合中对象的属性

问题描述 投票:0回答:1

我一直在 GitHub Copilot 上反复讨论这个问题,并且在 Gemini 和 ChatGPT 上也有过类似的经历,所有这些都给了我我已经尝试过的相同东西,并且在大多数情况下都给出了一些建议没用。

在 C#/WPF 中,我有一个枚举、一个包含枚举中的键和关联值的对象,以及这些对象的 KeyedCollection。例如

public enum MyEnum
{
    Key1,
    Key2,
    Key3
}

public class MyObject : ObservableObjectBase
{
    public MyEnum Key { get; set; }
    public string Value { get; set; }  // Actual implementation generates change event
}

public class MyCollection : KeyedCollection<MyEnum, MyObject>
{
    protected override MyEnum GetKeyForItem(MyObject item)
    {
        return item.Key;
    }
}

我需要使用枚举中的静态值将文本框(或任何组件)的文本绑定到 someCollection[key].Value 。 someCollection 将是包含控件的窗口的属性,因此可以从 DataContext 访问。 这看起来应该像

一样简单
<TextBox Text="{Binding Path=someCollection[namespace:MyEnum.Key2].Value, Mode=TwoWay}" />

这是每个 AI 都建议的方法之一,但它在 VS IDE 中给出“找不到用于绑定的 DataContext”消息,当然绑定不起作用。 someCollection 从上下文中可见,并且适用于访问它的其他组件(如下所示),就像我要使用的枚举键一样。 这里需要注意的一件事是枚举和 MyCollection/MyObject 代码都在单独的类库中,但这并不重要。 再说一次,我可以从下面的转换器 XAML 很好地访问这些相同的部分。

如果我使用转换器来提取对象(正如人工智能通常建议的那样),我不知道如何将控件绑定到 object.Value 而不仅仅是对象。 AI 会不断提出这一建议,但仅仅从转换器返回 MyObject 是行不通的。

我能够使用仅返回 Value 并获取/设置 Convert/ConvertBack 函数内引用对象中的值的转换器。

<TextBox Text="{Binding someCollection, Converter={StaticResource CollectionToValueConverter}, ConverterParameter={x:Static namespace:MyEnum.Key2}}" />

但是,在这种情况下,我会丢失对象中更改的事件,大概是因为控件没有直接绑定到对象。 我不想让集合传播更改的事件,因为每当更新一个值时,就会刷新每个值。

我还尝试过 AI 建议的 MultiBinding 和嵌套绑定方法,但从未起作用。 看起来确实应该可以使用对象转换器进行某种嵌套绑定,如下所示:

<TextBox Text="{Binding Path=Value, DataContext={Binding someCollection, Converter={StaticResource CollectionToObjectConverter}, ConverterParameter={x:Static namespace:MyEnum.Key2}}}" />

感谢您的任何建议。 这看起来应该是一件非常容易和常见的事情,但感觉越来越像众多“你无法从这里到达那里!”之一。我在 C# 和 WPF 中遇到的项目。

谢谢,

贝奥

c# wpf xaml binding ivalueconverter
1个回答
0
投票

someCollection 将是包含控件的窗口的属性,因此可以从 DataContext 访问。

仅当您实际设置 DataContext 时,这才是正确的,即像

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public MyCollection SomeCollection { get; } = // follow naming rule
        [
            new MyObject { Key = MyEnum.Key1, Value = "Value 1" },
            new MyObject { Key = MyEnum.Key2, Value = "Value 2" },
            new MyObject { Key = MyEnum.Key3, Value = "Value 3" }
        ];
}

在绑定表达式中,您将使用枚举值的字符串表示形式

Key2
。设置绑定
Mode
是多余的。

<TextBox Text="{Binding Path=SomeCollection[Key2].Value}" />
© www.soinside.com 2019 - 2024. All rights reserved.