简体   繁体   中英

ComboBox.SourceUpdated event is not fired

I have two ComboBoxes on my view. Both of them are bound to two different ObservableCollections in the ViewModel, and when the selected item in ComboBox1 is changed, ComboBox2 gets updated with a different collection. The binding works just fine, however, I want the second ComboBox to always select the first item in its collection. Initially, it works, however, when the source and items in ComboBox2 get updated, the selection index gets changed to -1 (ie the first item is no longer selected).

To fix this, I added a SourceUpdated event to ComboBox2 and method that the event calls changes the index back to 0. The problem is that the method is never called (I put a breakpoint at the very top of the method and it doesn't get hit). Here's my XAML code:

<Grid>
    <StackPanel DataContext="{StaticResource mainModel}" Orientation="Vertical">
        <ComboBox ItemsSource="{Binding Path=FieldList}" DisplayMemberPath="FieldName"
                  IsSynchronizedWithCurrentItem="True"/>

        <ComboBox Name="cmbSelector" Margin="0,10,0,0"
                  ItemsSource="{Binding Path=CurrentSelectorList, NotifyOnSourceUpdated=True}"
                  SourceUpdated="cmbSelector_SourceUpdated">
        </ComboBox>    
    </StackPanel>
</Grid>

And in the code-behind:

// This never gets called
private void cmbSelector_SourceUpdated(object sender, DataTransferEventArgs e)
{
    if (cmbSelector.HasItems)
    {
        cmbSelector.SelectedIndex = 0;
    }
}

Any help is appreciated.

After working on it for an hour I finally figured it out. The answer is based on this question: Listen to changes of dependency property.

So basically you can define a "Property Changed" event for any DependencyProperty on an object. This can be extremely helpful when you need to extend or add additional events to a control without having to create a new type. The basic procedure is like this:

DependencyPropertyDescriptor descriptor = 
   DependencyPropertyDescriptor.FromProperty(ComboBox.ItemsSourceProperty, typeof(ComboBox));

descriptor.AddValueChanged(myComboBox, (sender, e) => 
{ 
   myComboBox.SelectedIndex = 0;
});

What this does is that it creates a DependencyPropertyDescriptor object for the ComboBox.ItemsSource property, and then you can use that descriptor to register an event for any control of that type. In this case, every time the ItemsSource property of myComboBox is changed, the SelectedIndex property is set back to 0 (which means the first item in the list is selected.)

Copying your code into the IDE, after adding the using System.ComponentModel; clause and setting it to my ComboBox1, the IntelliSource tells me that "the name 'descriptor' does not exist in the current context....

    DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(ComboBox.ItemsSourceProperty, typeof(ComboBox));

    descriptor.AddValueChanged(ComboBox1, (sender, e)) => 
    { 
       ComboBox1.SelectedIndex = 0;
    });

Why should that be?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM