ComboBox does not select the correct item when binding to CompositeCollection

I have a ComboBox related to a collection of animals. From it I choose my favorite animal. I need a static null element over related elements. I declare this using CompositeCollection. When the ComboBox is tied, it does not select my original favorite animal. How can i fix this? A similar problem is here , but still not resolved.

remarks:

  • Binding to a static element works, i.e. if I donโ€™t have the original favorite animal, the selected static item.
  • The problem disappears if the static item is deleted. Of course, this would make the CompositeCollection and this whole question obsolete.

I have already applied these measures:

  • CollectionContainer cannot directly bind to the property specified here .
  • The composite collection also moves to a static resource, as suggested here .

Fill in the C # and XAML code to demonstrate the problem:

using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; namespace WpfApplication1 { public class Animal { public int Id { get; set; } public string Name { get; set; } } public class Zoo { private IEnumerable<Animal> _animals = new Animal[] { new Animal() { Id = 1, Name = "Tom" }, new Animal() { Id = 2, Name = "Jerry" } }; public Zoo(int initialId) { FavouriteId = initialId; } public int FavouriteId { get; set; } public IEnumerable<Animal> Animals { get { return _animals; } } } public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void BindComboBox(object sender, RoutedEventArgs e) { // Selecting the static item by default works. //DataContext = new Zoo(-1); // Selecting "Jerry" by default does not work. DataContext = new Zoo(2); } } } 

Xaml

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1"> <Window.Resources> <CollectionViewSource x:Key="AnimalsBridge" Source="{Binding Path=Animals}" /> <CompositeCollection x:Key="AnimalsWithNullItem"> <local:Animal Id="-1" Name="Pick someone..."/> <CollectionContainer Collection="{Binding Source={StaticResource AnimalsBridge}}" /> </CompositeCollection> </Window.Resources> <StackPanel> <Button Content="Bind" Click="BindComboBox"/> <ComboBox x:Name="cmbFavourite" SelectedValue="{Binding Path=FavouriteId}" SelectedValuePath="Id" DisplayMemberPath="Name" ItemsSource="{StaticResource AnimalsWithNullItem}"/> </StackPanel> </Window> 
+4
source share
1 answer

I do not have a solution to the problem, but an alternative. I personally have viewing models dedicated to each point of view. Then I would have a property on the view model to add a null value as needed. I prefer this method, as it allows me to better test the objects of my model.

In your example, add:

 public class ZooViewModel { ..... public IEnumerable<Animal> Animals { get { return _animals; } } public IEnumerable<Animal> AnimalsWithNull { get { return _animals.WithDefault(new Animal() { Id = -1, Name = "Please select one" }); } } } 

Magic component

 public static class EnumerableExtend { public static IEnumerable<T> WithDefault<T>(this IEnumerable<T> enumerable,T defaultValue) { yield return defaultValue; foreach (var value in enumerable) { yield return value; } } } 

Then in your XAML you just get attached to

 ComboBox x:Name="cmbFavourite" SelectedValue="{Binding Path=FavouriteId}" SelectedValuePath="Id" DisplayMemberPath="Name" ItemsSource="{Binding AnimalsWithNull }"/> 

Now you snap directly to the source and can control the binding as usual. Also note that because we use yield, we are not creating a new enumeration, but simply repeating an existing list.

+4
source

Source: https://habr.com/ru/post/1483595/


All Articles