ValueTuple不支持DisplayMemberPath。Combobox,WPF。

6
我有一个下拉框,想要将其ItemsSource绑定到一个IEnumerable<(string, string)>。如果我不设置DisplayMemberPath,则它可以工作,并在下拉区域中显示调用项的ToString()的结果。然而,当我设置DisplayMemberPath="Item1"时,它就不再显示任何内容了。我制作了以下示例,您可以看到如果我使用经典的Tuple类型,它会按预期工作。
调试时,我已检查valuetuple也具有Item1和Item2作为属性。
我的XAML:
<Window x:Class="TupleBindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Loaded="MainWindow_OnLoaded"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ComboBox x:Name="TupleCombo" Grid.Row="0" VerticalAlignment="Center" 
                  DisplayMemberPath="Item1" />
        <ComboBox x:Name="ValueTupleCombo" Grid.Row="1" VerticalAlignment="Center" 
                  DisplayMemberPath="Item1" />
    </Grid>
</Window>

我的代码后端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace TupleBindingTest
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private IEnumerable<Tuple<string, string>> GetTupleData()
        {
            yield return Tuple.Create("displayItem1", "valueItem1");
            yield return Tuple.Create("displayItem2", "valueItem2");
            yield return Tuple.Create("displayItem3", "valueItem3");
        }

        private IEnumerable<(string, string)> GetValueTupleData()
        {
            yield return ( "displayItem1", "valueItem1");
            yield return ("displayItem2", "valueItem2");
            yield return ("displayItem3", "valueItem3");
        }

        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            TupleCombo.ItemsSource = GetTupleData();
            ValueTupleCombo.ItemsSource = GetValueTupleData();
        }
    }
}

运行时,这个示例将在第一个组合框中正确显示数据,但在第二个组合框中不会显示任何内容。

为什么会发生这种情况?

1个回答

17

这是因为DisplayMemberPath内部为每个项模板设置了指定路径的绑定。因此,设置DisplayMemberPath="Item1"基本上等同于设置以下ComboBox.ItemTemplate

<DataTemplate>
    <ContentPresenter Content="{Binding Item1}" />
</DataTemplate>

现在, WPF 仅支持属性绑定。这就是为什么当您使用 Tuple 时它能够正常工作的原因 - 因为其成员是 属性,也是为什么当使用 ValueTuple 时它不能工作 - 因为其成员是 字段

尽管如此,在您的特定情况下,由于您仅将这些集合用作绑定源,因此可以使用匿名类型来实现您的目标(其成员也是属性),例如:

private IEnumerable<object> GetTupleData()
{
    yield return new { Label = "displayItem1", Value = "valueItem1" };
    yield return new { Label = "displayItem2", Value = "valueItem2" };
    yield return new { Label = "displayItem3", Value = "valueItem3" };
}

然后你可以通过以下方式设置你的ComboBox

<ComboBox DisplayMemberPath="Label" SelectedValuePath="Value" (...) />

4
故事的寓意是,ValueTuple 的项被公开为字段而不是属性,并且 WPF 不支持绑定到字段。 - Jeff Mercado

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接