2017-08-02 37 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(); 
     } 
    } 
} 

このサンプルでは、​​最初のコンボボックスにデータを適切に表示されますが、2番目には何も表示されません。

どうしてですか?

答えて

4

DisplayMemberPathは、内部的に各アイテムのテンプレートの指定されたパスでバインディングを設定するためです。だから、DisplayMemberPath="Item1"は基本的にComboBox.ItemTemplate次の設定の省略形です設定:今

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

WPFは、専用のプロパティへの結合をサポートしています。そのメンバーがのプロパティであり、そのメンバーがフィールドであるため、ValueTupleのメンバーとは異なる理由で、Tupleを使用すると問題なく動作します。

あなたは、単にバインディングソースとしてこれらのコレクションを使用するので、しかし、あなたはあなたの目標を達成するために 匿名型を使用することができ、あなたの特定のケースで

(そのメンバーはまた、プロパティある)、例えば:

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はありませんされていますフィールドへのバインドをサポートしていません。 –

関連する問題