Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

wpf - Selection bug for listbox where the list items are value types / structs and contain duplicates?

I turned an Horizontal ItemsControl to a Listbox so that I am able to select individual items but found that the selection was broken. Took some time to distill out the problematic bit.

Books = new[] { new Book{Id=1, Name="Book1"},
                                 new Book{Id=2, Name="Book2"},
                                 new Book{Id=3, Name="Book3"},
                                 new Book{Id=4, Name="Book4"},
                                 new Book{Id=3, Name="Book3"},
            };

            <DataTemplate DataType="{x:Type WPF_Sandbox:Book}">
                <TextBlock Text="{Binding Name}"/>
            </DataTemplate>

<ListBox ItemsSource="{Binding Books}"/>

If Book is a struct, the listbox selection (default mode : single) goes awry if you select an item which has an equivalent struct in the list. e.g Book3

If Book is turned into a class (with non-value type semantics), selection is fixed.

Choices (so far, don't like any of them):

  • I chose structs because its a small data structure and the value type semantics are useful in comparing 2 instances for equality. Changing it to a class causes me to lose value-type semantics.. I can't use the default Equals anymore or override it for memberwise comparison.
  • Add a differentiating Book attribute purely for the listbox selection to work (e.g. an Index).
  • Eliminate Duplicates.. Not possible.

WPF listbox : problem with selection : states that the Listbox is setting SelectedItem and while updating the UI for this, it just lights up all items in the list that Equal(SelectedItem). Not sure why.. highlighting SelectedIndex would make this problem go away; maybe I am missing something. ListBox is selecting many items even in SelectionMode="Single" : shows the same problem when list items are strings (value type semantics)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why not simply use a better collection class as your datasource to overcome the problem

var collection = new[]
 {
     new Book {Id = 1, Name = "Book1"},
     new Book {Id = 2, Name = "Book2"},
     new Book {Id = 3, Name = "Book3"},
     new Book {Id = 4, Name = "Book4"},
     new Book {Id = 3, Name = "Book3"},
 };
 var Books = collection.ToDictionary(b => Guid.NewGuid(), b => b);
 DataContext = Books;

And this will be your DataTemplate

<ListBox ItemsSource="{Binding}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Value.Name}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...