1

I have some WPF GUI (hosted in WinForm) which has multiple CheckBoxes. The default value of IsChecked of each CheckBox need come from different boolean fields in some background data. Each boolean field in the background data is mapped to a CheckBox in the VisualTree. So I bind the IsChecked property of each CheckBox to the CheckBox itself and use a Converter to fetch the corresponding boolean value in the background data. This way the CheckBox becomes an input to the Converter function so that the Converter can know its location in the VisualTree and query the correct boolean field in the background data. When the user changes the CheckBox, Checked/Unchecked event-handlers will set the value back to the boolean field in the background data. The XAML is like this:

    <DataTemplate x:Key="ModuleWithEnableControl">
        <WrapPanel>
            <CheckBox Content="Enable" 
                      IsChecked="{Binding Path=., RelativeSource={RelativeSource Mode=Self}, Mode=OneTime, 
                                  Converter={StaticResource moduleEnableDisableConverter}
                                  }"
                      Checked="ModuleEnabled" Unchecked="ModuleDisabled"
                />
        </WrapPanel>
    </DataTemplate>

The Converter code is like this:

class ModuleEnableDisableConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      System.Windows.Controls.CheckBox theBox = (System.Windows.Controls.CheckBox)value;
      //Here suppose to get the default value of the CheckBox
      //but just return true for now
      return true;
    }
}

The Checked handler code is like this:

    private void ModuleEnabled(object sender, RoutedEventArgs e)
    {
        MessageBoxResult result = MessageBox.Show("Enabled", "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question);
        if (result == MessageBoxResult.Yes)
        {
          //Check the sender (CheckBox)'s location in the VisualTree,
          //Do set the boolean field in the background data
        }
        return;
    }

When program starts, the Converter runs first, since it returns ture, then immediately the Checked handler ModuleEnabled runs. Then the problem happens when executing the MessageBox.Show() in the handler, a Popup window complains:

InvalidOperationException was unhandled by user code

and

Dispatcher processing has been suspended

but message are still being processed.

If I comment out the MessageBox.Show() line, the program executes as expected. If I don't bind the IsChecked to the CheckBox itself, no problem either, the MessageBox shows perfectly when user changes the CheckBox. I'm wondering why the MessageBox.Show() in the event-handler has conflict with the binding Converter? Also, is there a way to not trigger the Checked handler when setting the initial value using the binding?

4

0 回答 0