2010-12-01 45 views
0

當將數組綁定到ListBox時,我注意到了一些奇怪的行爲。當我添加具有相同「名稱」的項目時,我無法在運行時選擇它們 - ListBox變得瘋狂。如果我給他們獨特的「名字」,它就可以工作。任何人都可以請解釋爲什麼發生這種情況?在WPF中綁定到列表框時出現奇怪的行爲

的觀點:

<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> 

視圖模型:

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

在WPF ListBox中的所有項目必須是唯一的實例。由於字符串Interning,具有相同常數值的字符串不是唯一的實例。爲了解決這個問題,你需要封裝項目更有意義的對象不是一個字符串,如:

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

現在你可以實例化多個實例的DataItem並創建一個ItemDataTemplate呈現文本爲TextBlock。如果你想使用默認的渲染,你也可以重寫DataItem的ToString()。現在您可以擁有多個具有相同文本且沒有問題的DataItem實例。

這個限制看起來有點奇怪,但它簡化了邏輯,因爲現在SelectedItem與SelectedIndex與列表中的項目具有一一對應關係。它也符合WPF的數據可視化方法,這種方法傾向於有意義的對象列表,而不是普通字符串列表。

+2

它實際上不是關於唯一實例(引用相等),而是關於邏輯相等(虛擬等於方法)。如果兩個字符串具有相同的內容,即使它們是不同的引用,您也會從ListBox中得到奇怪的行爲。但是,是的,將它們包裝在一個不會覆蓋Equals的引用類型中可以解決問題。 – 2010-12-02 05:34:55

相關問題