WPF 派生 ComboBox SelectedValuePath 问题

发布于 2024-08-24 12:59:16 字数 1509 浏览 6 评论 0原文

在我们的应用程序中,我们有一个非常大的数据集,用作 ComboBox 列表等的数据字典。这些数据是静态缓存的,并由 2 个变量锁定,因此我认为编写一个从 ComboBox 派生并公开的控件是明智的2 个按键作为 DP。当这两个键具有正确的值时,我会自动从其对应的数据字典列表中设置 ComboBox 的 ItemsSource。我还自动将构造函数中的 SelectedValuePath 和 DisplayMemberPath 分别设置为 Code 和 Description。

以下是数据字典列表中的 ItemsSource 中的项目始终如何显示的示例:

public class DataDictionaryItem
{
    public string Code { get; set; }
    public string Description { get; set; }
    public string Code3 { get { return this.Code.Substring(0, 3); } }
}

Code 的值始终为 4 个字符长,但有时我只需要绑定其中的 3 个字符。因此,Code3 属性。

以下是用于设置 ItemsSource 的自定义组合框内的代码的外观:

private static void SetItemsSource(CustomComboBox combo)
{
    if (string.IsNullOrEmpty(combo.Key1) || string.IsNullOrEmpty(combo.Key2))
    {
        combo.ItemsSource = null;
        return;
    }

    List<DataDictionaryItem> list = GetDataDictionaryList(combo.Key1, combo.Key2);
    combo.ItemsSource = list;
}

现在,我的问题是,当我将 XAML 中的 SelectedValuePath 更改为 Code3 时,它不起作用。我绑定到 SelectedValue 的内容仍然从 DataDictionaryItem 获取完整的 4 个字符代码。当 SelectedValuePath 更改并且没有骰子时,我什至尝试重新运行 SetItemsSource。

谁能看到我需要做什么才能让我的自定义组合框唤醒并使用提供的 SelectedValuePath(如果它在 XAML 中被覆盖)?调整 SelectedValue 绑定业务对象中的属性设置器中的值不是一个选项。

以下是 XAML 如何以表单形式查找我的组合框:

<c:CustomComboBox Key1="0" Key2="8099" SelectedValuePath="Code3" SelectedValue="{Binding Thing}"/>

编辑:我刚刚对我的代码运行了窥探,它说我的 SelectedValuePath 是 Code...它似乎从未设置为 Code3。 ..祖?

In our application we have a very large set of data that acts as our data dictionary for ComboBox lists, etc. This data is staticly cached and keyed off of 2 variables, so I thought it wise to write a control that derived from ComboBox and exposed the 2 keys as DPs. When those 2 keys have proper values I set the ItemsSource of the ComboBox automatically from the data dictionary list it corresponds to. I also automatically set the SelectedValuePath and DisplayMemberPath in the constructor to Code and Description, respectively.

Here's how an example of how an item in the ItemsSource from the data dictionary list always looks:

public class DataDictionaryItem
{
    public string Code { get; set; }
    public string Description { get; set; }
    public string Code3 { get { return this.Code.Substring(0, 3); } }
}

The value of Code is always 4 characters long, but sometimes I only need to bind 3 characters of it. Hence, the Code3 property.

Here's how the code looks inside my custom combobox to set the ItemsSource:

private static void SetItemsSource(CustomComboBox combo)
{
    if (string.IsNullOrEmpty(combo.Key1) || string.IsNullOrEmpty(combo.Key2))
    {
        combo.ItemsSource = null;
        return;
    }

    List<DataDictionaryItem> list = GetDataDictionaryList(combo.Key1, combo.Key2);
    combo.ItemsSource = list;
}

Now, my problem is, when I change the SelectedValuePath in the XAML to Code3, it doesn't work. What I bind to SelectedValue still gets the full 4 character Code from DataDictionaryItem. I even tried rerunning SetItemsSource when the SelectedValuePath was changed and no dice.

Can anyone see what I need to do to get my custom combobox to wake up and use the SelectedValuePath provided if it's overridden in the XAML? Tweaking the value in the property setter in my SelectedValue bound business object is not an option.

Here's how the XAML looks for my combobox in a form:

<c:CustomComboBox Key1="0" Key2="8099" SelectedValuePath="Code3" SelectedValue="{Binding Thing}"/>

EDIT: I just ran snoop on my code and it says my SelectedValuePath is Code... it doesn't appear to ever be set to Code3... Zuh?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨轻弹 2024-08-31 12:59:16

好吧,我明白了。

显然,在 WPF 控件的默认非静态构造函数中设置 DependencyProperty 的默认值是不允许的。所以,一开始我尝试了这个:

static ValueCodeListComboBox()
{
  SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Code"));
  DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Description"));
}

但这一直抛出一个错误:

元数据覆盖和基本元数据必须是相同类型或派生类型。

最后发现这意味着我需要使用 FrameworkPropertyMetadata 而不是 PropertyMetadata:

static ValueCodeListComboBox()
{
  SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Code"));
  DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Description"));
}

现在更改 XAML 中的 SelectedValuePath 效果很好。

Ok, I figured it out.

Apparently setting the default values of a DependencyProperty in the default non-static constructor of a WPF control is a no-no. So, at first I tried this:

static ValueCodeListComboBox()
{
  SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Code"));
  DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new PropertyMetadata("Description"));
}

But this kept throwing an error saying:

Metadata override and base metadata must be of the same type or derived type.

Finally figured out that meant I needed to use FrameworkPropertyMetadata instead of PropertyMetadata:

static ValueCodeListComboBox()
{
  SelectedValuePathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Code"));
  DisplayMemberPathProperty.OverrideMetadata(typeof(ValueCodeListComboBox), new FrameworkPropertyMetadata("Description"));
}

Now changing SelectedValuePath in the XAML works great.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文