0
votes

I have a Custom Control derived from a ComboBox where I use a CompositeCollection to "merge" the original ItemsSource with additional Objects.

The problem is, that

CompositeCollection comp = new CompositeCollection();
SomeLogic();
ItemsSource = comp;

Setting the ItemsSource to the composed Collection is setting SelectedItem to null and invoke the Binding TwoWay Binding to the ViewModel. The SelectedItem bound property in my ViewModel will then be 'null'.

I am currently workarounding this by restoring the SelectedItem after assigning the ItemsSource:

 Object priorSelectedItem = SelectedItem;
 ItemsSource = comp;    
 SelectedItem = priorSelectedItem;

However this just fixes the value of SelectedItem in my ViewModel, a nasty sideeffect is that the when the Object changes some logic is run in the Setter. E.G. setting a

_dataHasChanged = true; 

Flag.

So if there is any way I can

a) Prevent the SelectedItem to get reset whilst changing the ItemsSource

or

b) Prevent the SelectedItem-Binding to be Invoked whilst changing the ItemsSource

from within the Custom Control (Don't want to take care of 20 ViewModels because there is a flaw in the Control) I would greatly appreciate any input on how to do so :-)

1
can't you just set your 2way binding on SelectedItem after initializing ItemsSource ?Sisyphe
Dont think so... I bind the ItemsSource and SelectedItem in XAML Binding Expressions, and then change the ItemsSource to a manipulated Version in my Control. Don't think it is possible to tell my object in which order to set the bindings specified in XAML, is it?Steav
I think First binding in xaml will be resolved first. So if you binded itemsSource after SelectedItem in your XAML, try to do the opposite !Sisyphe

1 Answers

0
votes

I've managed to prevent this behavior by saving the SelectedItem-Binding in a private variable in OnApplyTemplate(), then clearing it and Set it back to the variable value after the new ItemsSource has been applied.

    private Binding _selectedItemBinding;
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _selectedItemBinding = BindingOperations.GetBinding(this, ComboBox.SelectedItemProperty);
        BindingOperations.ClearBinding(this, ComboBox.SelectedItemProperty);
        if (BindingOperations.IsDataBound(this, ComboBox.SelectedItemProperty))
            this.SetBinding(ComboBox.SelectedItemProperty, "dummy");
        ...
    }

 private void AdaptItemSource()
 {
   Object priorSelectedItem = SelectedItem;
   ItemsSource = comp;    
   SelectedItem = priorSelectedItem;

   BindingOperations.SetBinding(this, ComboBox.SelectedItemProperty, _selectedItemBinding);
 }

This did the Trick for me