1

I have a listview with Combobox in it:

<ListView x:Name="DiscountListView" Grid.Row="1" ItemsSource="{Binding DiscountMatrix.RelatedDiscounts}" Margin="0, 7, 0, 0" Style="{StaticResource AppTransparentListViewStyle}"> <ListView.View> <GridView> <GridViewColumn Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor , AncestorType=ListView, AncestorLevel=1},Path=ActualWidth}"> <GridViewColumn.CellTemplate> <ItemContainerTemplate> <Grid HorizontalAlignment="Stretch" Margin="-7, 14, 0, 0" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor , AncestorType=ListViewItem, AncestorLevel=1},Path=ActualWidth}"> <Border BorderBrush ="{Binding SelectedDiscount.IsNotRelated, Converter={StaticResource DisablingBoolToColorConverter}}" BorderThickness="2" Margin="4, 0, 15, 0"> <customComboBox:CustomComboBox x:Name="DiscountView" DisplayMemberPath="Name" Margin="0, 8, 5, 0" Text="{Binding SelectedDiscount.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue ="{Binding SelectedDiscount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <customComboBox:CustomComboBox.ItemsSource> <CompositeCollection> <ComboBoxItem Content="{DynamicResource lang_Common_SelectItem}" IsEnabled="False" /> <CollectionContainer Collection="{Binding Source={StaticResource Discounts}}" /> </CompositeCollection> </customComboBox:CustomComboBox.ItemsSource> </customComboBox:CustomComboBox> </Border> </Grid> </ItemContainerTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView> </Grid> 

According to my logic RelatedDiscounts (actually my listview) is a list of SelectedDiscounts. I can add a discount and it will be set as SelectedItem in my Combobox (for this I should ovverride Equals in SelectedDiscount class). Every discount has IsNotRelated property (true/false depending on logic). I faced with a problem: f.e. my first list item SelectedDiscount was set as a SelectedItem in the first Combobox and it's IsNotRelated property is false by logic. Then I add the same item as SelectedItem to my second Combobox but IsNotRelated property is true. In this case first SelectedDiscount's property IsNotRelated becomes also true but should stay false. I know it's because the second time I set true for SelectedDiscount property from ItemSourse of all my Comboboxes. My question is: how can I set property only for SelectedItem of current Combobox but not for this item in ItemSourse at all? Any ideas how can I avoid standart behavior of Combobox and sorry for my English.

Here is a part of SelectedDiscount's type (DiscountModel):

public bool _isNotRelated; [JsonIgnore] public bool IsNotRelated { get { return _isNotRelated; } set { _isNotRelated = value; RaisePropertyChangedEvent("IsNotRelated"); } } public override bool Equals(object obj) { var other = obj as DiscountModel; return (Id == other?.Id); } 

1 Answer 1

1

My apologies if I am misunderstanding your issue...

The reason you are most likely seeing this is because the object SelectedDiscount you are binding each ComboBox to is the same mutable object. Though the object is listed in separate collections, it is the same object in memory. The collection is simply holding a reference to the SelectedDiscount objects in memory, not the object itself.

For example:

var list1 = new List<SelectedDiscount>(); var list2 = new List<SelectedDiscount>(); SelectedDiscount sd = new SelectedDiscount(); list1.Add(sd); list2.Add(sd); //Change Collection 1 list1[0].IsNotRelated = true; //Both collections return true Console.WriteLine(list1[0].IsNotRelated); //True; Console.WriteLine(list2[0].IsNotRelated); //True; 

You won't see this problem immutable objects such as string as they cannot change. Each collection will build it's own version of the object, not a reference like with a mutable object.

Essentially, you will need to create a new instance of the SelectedDiscount object in memory to modify one without the other being modified.

One way to do this is by implementing ICloneableonto your class.

public class SelectedDiscount : ICloneable { [JsonIgnore] public bool IsNotRelated { get { return _isNotRelated; } set { _isNotRelated = value; RaisePropertyChangedEvent("IsNotRelated"); } } public object Clone() { return this.MemberwiseClone(); } } 

Now you can clone the object into the new collection.

var list1 = new List<SelectedDiscount>(); var list2 = new List<SelectedDiscount>(); //Assuming the IsNotRelated property is defaulted to false. SelectedDiscount sd = new SelectedDiscount(); list1.Add(sd); list2.Add((SelectedDiscount)sd.Clone()); //Change Collection 1 list1[0].IsNotRelated = true; //Only the first collection will return true Console.WriteLine(list1[0].IsNotRelated); //True; Console.WriteLine(list2[0].IsNotRelated); //False; 

You may also implement you own ways to clone as sometimes ICloneable may not work depending on class structure. I simply wanted to give you an example, but now that you know WHY it's behaving the way it is, you can address the issue.

Best Wishes!

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.