Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: ComboBox, comparing objects based on identifying property

Tags:

combobox

wpf

xaml

Let's say I have a Class, let's name it Parent. This class has as a property a object of another class, let´s call it Child. Child has a int property ID.

Now instances of these classes are based on rows in database tables.

So let's say Parent has Child instance with ID=4 and in my program there will be a Dropdown list with all available Child instances so we can change the instance in Parent.

Problem is that because of bad design the list with all the child objects is instanced on a seperate occasion from the Child inside the parent so even if they both have ID=4 it won't recognize them as same object ( because of course it isn't ).

However I still wan't the same ID object being the default one for the ComboBox. I should somehow of course just reference the ID somehow but I'm a little bit slow in the dark month of december and I'm not seeing how to do it because it's still the object I'm setting not only int value.

Here is the XAML code:

 <DataTemplate x:Key="EditTemplate" DataType="{x:Type data:Parent}">
      <ComboBox ItemsSource="{Binding ElementName=Panel, Path=DataContext.ChildList}"
                              SelectedItem="{Binding Path=Child, Mode=TwoWay}"
                              SelectedValuePath="ID" DisplayMemberPath="Name" />
 </DataTemplate>
like image 849
Ingó Vals Avatar asked Dec 28 '22 03:12

Ingó Vals


2 Answers

so even if they both have ID=4 it won't recognize them as same object ( because of course it isn't )

It sounds like the root problem is equality, override the necessary methods for the given child object to reach the definition of equality that suits your needs.

public override bool Equals(object obj)
   {
      Child other = obj as Child;
      if( other == null )
      {
         return false;
      }
 
      return (this.Id == other.Id);
   }
 
   public override int GetHashCode()
   {
      return this.Id.GetHashCode();
   }
 
   public static bool operator == (Child me, Child other)
   {
      return Equals(me, other);
   }
 
   public static bool operator != (Child me, Child other)
   {
      return !Equals(me, other);
   }
like image 111
Aaron McIver Avatar answered Mar 05 '23 16:03

Aaron McIver


In case anyone else comes across this again and wants a XAML solution, you can also use the SelectedValuePath and SelectedValue property along with the SelectedItem property.

<DataTemplate x:Key="EditTemplate" DataType="{x:Type data:Parent}">
  <ComboBox ItemsSource="{Binding ElementName=Panel, Path=DataContext.ChildList}"
                          SelectedItem="{Binding Path=Child, Mode=TwoWay}"
                          SelectedValue="{Binding Path=Child.ID, Mode=OneWay}"
                          SelectedValuePath="ID" DisplayMemberPath="Name" />
</DataTemplate>

NOTE: Obviously this isn't best practice to have two bindings to the selection, so use with caution.

like image 29
Kyle Avatar answered Mar 05 '23 15:03

Kyle