locked
Bug with ComboBox Binding - Code on a non-visible page can run RRS feed

  • Question

  • If you happen to be sharing a ViewModel between two Pages, and both pages have XAML ComboBoxes that bind their ItemsSource and SelectedItem to the ViewModel, it's possible that code on a non-visible page will run. Here's a snippet:

    <!-- First Page --> <ComboBox ItemsSource="{Binding Titles}" SelectedItem="{Binding Title, Mode=TwoWay}" SelectionChanged="ComboBox_SelectionChanged"/>

    <Button Click="Button_Click"/> ... <!-- Second Page --> <ComboBox ItemsSource="{Binding Titles}" SelectedItem="{Binding Title, Mode=TwoWay}"/>


    and the code behind:

    // First Page protected void OnNavigatedTo(NavigationEventArgs e) { var vm = new ViewModel(); vm.Title = vm.Titles[0]; this.DataContext = vm; } private void ComboBox_SelectionChanged(...) { // Fires when this Page's ComboBox changes AND when the second Page's ComboBox changes }

    private void Button_Click(...)

    {

    this.Frame.Navigate(typeof(SecondPage), this.DataContext);

    }

    // Second Page protected void OnNavigatedTo(NavigationEventArgs e) { this.DataContext = e.Parameter; } // ViewModel public class ViewModel : INotifyPropertyChanged { public string Title { ... } public List<string> Titles { ... } }


    The first Page's ComboBox_SelectionChanged() event will be fired when the user changes ComboBox selection on Page 2. This causes very unexpected behavior and I cannot find a work-around.

    Here is a simple working example.


    • Edited by CryclopsApps Tuesday, January 7, 2014 5:39 AM update to code snippets
    Tuesday, January 7, 2014 5:29 AM

All replies

  • You can not prevent the event from firing, because after all you created a two way binding. So this behavior is rather expected. If you don't want the invisible page to react, then you should check if the page is currently displayed. You can do this e.g. by starting your combobox selectionchanged event handler with the following code:

    // Don't react when page not active.
    if(Frame.CurrentSourcePageType != this.GetType()) return;

    Tuesday, January 7, 2014 8:01 AM
  • Thanks for that snippet, I'll add that as a workaround for now.

    If this behavior is expected when there's a two way binding, why doesn't it repro with a TextBox (the linked example includes that)?

    <!-- First Page XAML -->
    
    <TextBox
        Text="{Binding Title, Mode=TwoWay}"
        TextChanged="TextBox_TextChanged"/>

    If the ViewModel.Title is changed on the second Page, the TextBox_TextChanged event handler does not fire on the first Page. It seems reasonable to expect ComboBox and TextBox to behave similarly here.

    Wednesday, January 8, 2014 7:52 PM
  • That's a good observation. I guess you have a candidate bug report here.
    Wednesday, January 8, 2014 9:18 PM