2010-10-02 31 views
7

我所遇到的代碼很奇怪的東西,簡單的WPF應用程序列表框甚至在的SelectionMode選擇許多項目=「單」

<Window x:Class="ListBoxSelection.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <ListBox ItemsSource="{Binding Path=Strings}" SelectionMode="Single"/> 
    </Grid> 
</Window> 

背後

public class ViewModel 
{ 
    public List<string> Strings { get; set; } 

    public ViewModel() 
    { 
     Strings = new List<string>(); 
     Strings.Add ("A"); 
     // add many items ... 
     Strings.Add ("A"); 
    } 
} 

/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = new ViewModel(); 
    } 
} 

,當我點擊單個項目,

Why multiple values selected?

,如果我繼續單擊物品,T嘿只是聚合。點擊一個已經選擇的項目什麼都不做。抓住我的頭,我以前有ListBoxes的數據綁定列表,以前從未見過。運行Win7(64),VS2010,行爲提供了.Net 3.5,.Net 3.5客戶端配置文件,.Net 4和.Net 4客戶端配置文件。

Arg,我應該提到我期待正常的默認單選行爲。

+4

我懷疑這是因爲所有的選擇實際上都是同一個實例(對同一個常量字符串的所有引用都一樣)。 – 2010-10-02 00:09:40

+0

檢查SelectedItems屬性。也許它只是選擇一個項目,但風格中的東西被搞砸了。 – 2010-10-02 00:12:21

+0

@丹。這是一個有趣的理論,我會自己測試,但我必須馬上離開。 – 2010-10-02 00:13:43

回答

11

Dan Bryant在他的評論中得到了大部分答案。

這裏發生了什麼是字符串實習。當您創建一串具有相同值的字符串時,.Net通過將所有對同一字符串值的引用實際引用同一個字符串對象來節省內存使用量。 (詳見this

我真的不知道爲什麼ListBox的行爲與它的行爲完全相同,也就是第一次選擇列表中的任何項目時,它會選擇該項目和列表中的第一項。但是它不會取消選擇何時點擊新項目,因爲檢查SelectedItem是否與剛剛單擊的項目不同,而不是。

public class TestObject 
{ 
    public override string ToString() 
    { 
     return GetHashCode().ToString(); 
    } 
} 

MainWindow.xaml

<ListBox x:Name="MyListBox" ItemsSource={Binding}"/> 

MainWindow.xaml.cs

ObservableCollection<TestObject> test = new ObservableCollection<TestObject>(); 
TestObject t = new TestObject(); 
test.Add(t); 
test.Add(t); 
test.Add(t); 
test.Add(t); 
test.Add(t); 
test.Add(t); 
MyListBox.DataContext = test; 
+0

接受丹的評論和增加一些你自己的更多答案。道歉丹,雖然第一次在現場的榮譽。想知道爲什麼ListBox在遇到這種特定場景時以這種方式行事... – 2010-10-02 01:00:17

+2

@johnny g,我認爲這是WPF背後的設計原理的一個產物,它是一個列表框代表不同的數據項列表。您通常不會直接綁定字符串,而是將數據項呈現爲字符串(通過DataTemplate或DisplayMember),這意味着您應該擁有唯一的數據項,即使呈現的字符串在某些情況下是相同的。如果您需要在具有相同表示的項目之間進行選擇,則仍需要有一些數據對象來編碼它們的不同方式(它們必須不同或者不會有兩個選項) – 2010-10-02 01:33:55

+2

如果非唯一項目是預期用例,'SelectedItem'不會是一個明智的屬性。 – 2010-10-02 09:24:40

7

我遇到

我由一個列表框綁定到測試對象的集合了完全一樣的行爲這個問題 - 正如其他人所指出的,.NET在一個好奇的m中處理字符串提高內存管理。

我的直接解決方法是創建一個UniqueListItem類來代替我打算添加到列表框中的字符串。

class UniqueListItemObject 
{ 
    private string _text; 
    public string Text { get { return _text; } set { _text = value; } } 

    public UniqueListItemObject(string input) 
    { 
     Text = input; 
    } 
    public UniqueListItemObject() 
    { 
     Text = string.Empty; 
    } 

    public override string ToString() 
    { 
     return Text; 
    } 
} 

因爲這個對象將獲得自己的存儲位置,添加此對象的實例到列表框控件,而不是添加字符串將導致唯一的選擇,即使在列表框中顯示的字符串是相同的每個實例。

 yourListBox.Items.Add(new UniqueListItemObject(yourStringHere); 

我不能說這是否是最好的解決方案(這取決於項目的要求),但希望有人認爲這很有幫助。

+0

如何從列表框中添加數據後,從這個?請幫幫我。 – 2013-08-21 14:04:51