【问题标题】:ValueTuple does not support DisplayMemberPath. Combobox, WPF [duplicate]ValueTuple 不支持 DisplayMemberPath。组合框,WPF [重复]
【发布时间】:2018-01-10 03:12:27
【问题描述】:

我有一个组合框,想将它的 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();
        }
    }
}

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

为什么会这样?

【问题讨论】:

    标签: c# wpf c#-7.0 valuetuple


    【解决方案1】:

    这是因为DisplayMemberPath 在内部为每个项目的模板设置了与指定路径的绑定。所以设置DisplayMemberPath="Item1" 基本上是设置以下ComboBox.ItemTemplate 的简写:

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

    现在WPF 只支持绑定到属性。这就是为什么当您使用 Tuples 时它可以正常工作的原因 - 因为它的成员是 properties,也是为什么它不适用于 ValueTuples - 因为它的成员是 fields.

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

    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" (...) />
    

    【讨论】:

    • 故事的寓意,ValueTuple 的项目作为字段而不是属性公开,并且 WPF 不支持绑定到字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多