2017-08-02 49 views
0

我有一个组合框,并希望将其ItemsSource绑定到IEnumerable<(string,string)>。如果我没有设置DisplayMemberPath,那么它将起作用,并在下拉区域显示在项目中调用ToString()的结果。不过,当我设置DisplayMemberPath="Item1"它不再显示任何东西。我做了以下示例,其中您可能会看到如果使用经典Tuple类型,则按预期工作。ValueTuple不支持DisplayMemberPath。组合框,WPF

在调试时,我已经检查到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(); 
     } 
    } 
} 

在运行这个样本将正确显示数据在第一组合框,但会什么都不显示在第二位。

为什么会发生这种情况?

回答

4

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

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

现在WPF只支持绑定属性。这就是为什么当您使用Tuple s时它工作正常 - 因为它的成员是属性,以及为什么它不能与ValueTuple s一起使用 - 因为它的成员是字段

你的具体情况虽然,因为你用这些藏品仅作为绑定源,你可以使用匿名类型来实现自己的目标(其成员也性质),例如:

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

这个故事告诉我们,一个'ValueTuple'的项目被暴露领域,而不是性能,和WPF做不支持绑定到字段。 –