2010-12-01 15 views
0

配列をListBoxにバインドするときに、奇妙な動作に気付きました。同じ「名前」のアイテムを追加すると、実行時にそれらを選択することはできません。リストボックスは狂ってしまいます。私がそれらにユニークな "名前"を付けると、うまく動作します。誰も説明してくださいなぜこれは起こっている?WPFでListBoxにバインドするときの奇妙な動作

ビュー:

<Window x:Class="ListBoxTest.ListBoxTestView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:ListBoxTest" 
     Title="ListBoxTestView" Height="300" Width="300"> 
    <Window.Resources> 
     <local:ListBoxTestViewModel x:Key="Model" /> 
    </Window.Resources> 
    <Grid DataContext="{StaticResource ResourceKey=Model}"> 
     <ListBox ItemsSource="{Binding Items}" Margin="0,0,0,70" /> 
     <Button Command="{Binding Path=Add}" Content="Add" Margin="74,208,78,24" /> 
    </Grid> 
</Window> 

ビューモデル:WPFのListBoxで

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows.Input; 

namespace ListBoxTest 
{ 
    internal class ListBoxTestViewModel : INotifyPropertyChanged 
    { 
     private List<string> realItems = new List<string>(); 

     public ListBoxTestViewModel() 
     { 
      realItems.Add("Item A"); 
      realItems.Add("Item B"); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     public string[] Items 
     { 
      get { return realItems.ToArray(); } 
     } 

     public ICommand Add 
     { 
      // DelegateCommand from Prism 
      get { return new DelegateCommand(DoAdd); } 
     } 

     private int x = 1; 
     public void DoAdd() 
     { 
      var newItem = "Item"; 
      // Uncomment to fix 
      //newItem += " " + (x++).ToString(); 
      realItems.Add(newItem); 
      OnPropertyChanged("Items"); 
     } 
    } 
} 

答えて

2

すべての項目は、固有のインスタンスでなければなりません。同じ定数値を持つ文字列は、文字列インターンのために一意のインスタンスではありません。今、あなたは複数のDataItemインスタンスをインスタンス化し、TextBlockのテキストをレンダリングするItemDataTemplateを作成することができます

public class DataItem 
{ 
    public string Text { get; set; } 
} 

:この問題を回避するには、次のような、文字列よりもっと有意義なオブジェクト内の項目をカプセル化する必要があります。既定のレンダリングを使用する場合は、DataItem ToString()をオーバーライドすることもできます。同じTextで問題のない複数のDataItemインスタンスを作成できるようになりました。

この制限は少し奇妙に見えるかもしれませんが、SelectedItemはSelectedIndexと1対1で対応しているため、ロジックが簡単になります。また、データ視覚化に対するWPFのアプローチと一致しています。これは、単純な文字列のリストではなく、意味のあるオブジェクトのリストに向かう傾向があります。

+2

これは実際には一意のインスタンス(参照の等価)ではなく、論理的な等価性(仮想のEqualsメソッド)に関するものです。 2つの文字列の内容が同じ場合、異なる参照であってもListBoxから奇妙な動作が発生します。しかし、はい、Equalsをオーバーライドしない参照型でそれらをラップすると、問題が解決されます。 –

関連する問題