It is dangerous to bind Radio Buttons to an enumeration with ValueConverter!

Binding a set of Radio Buttons to an enumeration is ubiquitous task but it’s not as easy as it might seem at first glance.

The Problem

One proposed way to do this is to bind each RadioButton IsChecked property to the property (defined somewhere in data model) providing current (selected) enumeration value and use ValueConverter with parameter to convert this current value to boolean and vice versa. This approach is recommended in some rather recent blog and forum posts, e.g. WPF: How to bind RadioButtons to an enum?, Databinding enum to radiobuttons, etc. It works when you change current enumeration value by hands in UI, but if you do it in code the button loses its binding! In that case you have the bug which isn’t easy to reveal.

The Example

Mark Smith (Julmar) uncovered the reason of this behavior in his excellent blog post MVVM: Binding RadioButton groups. In this post I want to show what happens by example. I took most of the code relevant to Radio Buttons to the enumeration binding from WPF: How to bind RadioButtons to an enum? forum thread. The window of the example looks like follows:

 

Fig. 1 Example screen until you change selections by clicking RadionButtons.

There are two panes in this window with subtle differences.

The left pane uses ValueConverter named “EnumBooleanConverter”:

public class EnumBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if (parameterString == null)
            return DependencyProperty.UnsetValue;

        if (Enum.IsDefined(value.GetType(), value) == false)
            return DependencyProperty.UnsetValue;

        object parameterValue = Enum.Parse(value.GetType(), parameterString);

        return parameterValue.Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if (parameterString == null || value.Equals(false))
            return DependencyProperty.UnsetValue;

        return Enum.Parse(targetType, parameterString);
    }
}
and corresponding XAML:
<StackPanel>
    <RadioButton Name="rb11" IsChecked="{Binding Path=CurrentChoice1, 
        Converter={StaticResource enumBooleanConverter}, 
        ConverterParameter=One}">One</RadioButton>
    <RadioButton Name="rb12" IsChecked="{Binding Path=CurrentChoice1, 
        Converter={StaticResource enumBooleanConverter}, 
        ConverterParameter=Two}">Two</RadioButton>

    <Button Click="btnNext1_Click" Margin="2">Next choice</Button>
    <Button Click="btnRandom1_Click" Margin="2">Random choice</Button>
</StackPanel>

The right pane uses ValueConverter named “EnumBooleanConverter2”:

public class EnumBooleanConverter2 : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value.Equals(false))
            return DependencyProperty.UnsetValue;
        else
            return parameter;
    }
}
and corresponding XAML:
<StackPanel>
    <RadioButton Name="rb21" IsChecked="{Binding Path=CurrentChoice2, 
        Converter={StaticResource enumBooleanConverter2}, 
        ConverterParameter={x:Static local:Choices.One}}"
        Content="{x:Static local:Choices.One}"/>
    <RadioButton Name="rb22" IsChecked="{Binding Path=CurrentChoice2, 
        Converter={StaticResource enumBooleanConverter2}, 
        ConverterParameter={x:Static local:Choices.Two}}"
        Content="{x:Static local:Choices.Two}"/>
    ...
    <Button Click="btnNext2_Click" Margin="2">Next choice</Button>
    <Button Click="btnRandom2_Click" Margin="2">Random choice</Button>
</StackPanel>

 

Both panes behave the same way. Until you change selected value by clicking RadionButtons all works fine and the screen looks like in Fig. 1. the “Current choice” filed reflects the option selected and the “Binding expr” field shows text “not null”: this means that RadionButton IsChecked property keeps the binding set in XAML. But if you click “Next” and, especially, “Random” buttons some times the picture changes radically:

Fig. 2 Example screen after you clicked “Next” or “Random” buttons some times.

As you can see the “Binding expr” field shows text “null”: this means that RadionButton IsChecked property lost the binding set in XAML and the current value property is no more connected to the RadioButton. You still can click a RadioButton and it will shows up in checked state but the current value property wouldn’t change.

Conclusion

You can bind Radio Buttons to an enumeration using ValueConverter on your own risk and only if you are sure that you won’t ever change the current value property programmatically.

Code

You can download VS 2008 example solution here

Posted in Uncategorized | 1 Comment

Remarkable post on Programmatically Selecting an Item in a WPF TreeView

It’s been a long time since I last posted anything but that doesn’t mean that I stop programming; I just have one huge project at hands which takes all my time.

At mean time I have struck against the old (July 2008) and fine blog post on the technique to select (and make visible) an arbitrary item in the data-bound TreeView: Programmatically Selecting an Item in a TreeView. The tricks are accomplished in TreeView extension class, the code is compact and, I witness, it works fine. At least for medium-sized TreeView.

Technorati Теги: ,,

Posted in Uncategorized | 1 Comment

ColorChooser Control

This element is the one more control from the ColorPicker constituent controls bug in addition to the published in my recent posts.

The ColorChooser control is the User Control containing the KnownColorPicker and RainbowColorPicker as alternative ways to pick the color and the OpacitySlider to set its opacity. It resembles the Windows Common Color Dialog which we are accustomed to.

That is the sample.

The ColorChooser has the SelectedColor Dependency Property used to get or set the value of the Color selected. When the SelectedColor changes the ColorChooser raises the SelectedColorChanged event.

On the base of the ColorChooser control the ColorDialog dialog is built .

The code

You can download the code and the samples here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/WPFGears/WPFGears.zip

The archive contains my WPFGears library with samples, tests, etc. It’s the Visual Studio 2008 SP1 solution targeted to .NET Framework 3.5.

You’ll find ColorChooserSample and ColorDialogSample projects there. The ColorChooser control and the ColorDialog  dialog code is in the WPFGears library project ColorPickerControls folder.

Regards,
Oleg V. Polikarpotchkin

Technorati Теги: ,,
Posted in Uncategorized | 2 Comments

AllInOneColorChooser Control

This element is the one more control from the ColorPicker constituent controls bug in addition to the published in my recent posts.

The AllInOneColorChooser control is the User Control composed of all the components which were developed as the parts of the ColorPicker controls bag. It provides you with the four different color pickers, and you can choose the one you are filling the most comfortable with. In addition it allows to set the color opacity with the opacity slider.

The pictures below show you different color pickers in action.

Sincerely I don’t think that it would be very good idea to use AllInOneColorChooser in the production code. Rather you could regard it as the toy allowing you to try and compare different possibilities in one place and then choose one you prefer.

The AllInOneColorChooser has the SelectedColor Dependency Property used to get or set the value of the Color selected. When the SelectedColor changes the AllInOneColorChooser raises the SelectedColorChanged event.

The code

You can download the code and the samples here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/WPFGears/WPFGears.zip

The archive contains my WPFGears library with samples, tests, etc. It’s the Visual Studio 2008 SP1 solution targeted to .NET Framework 3.5.

You’ll find AllInOneColorChooserSample project there. AllInOneColorChooser control code is in the WPFGears library project ColorPickerControls folder.

Regards,
Oleg V. Polikarpotchkin

Technorati Теги: ,,
Posted in Uncategorized | Leave a comment

KnownColorPicker Control

This element is the one more control from the ColorPicker constituent controls bug in addition to the published in my recent posts.

The KnownColorPicker control is designed as the tool to select the Color from the set of predefined colors. It’s the very simple User Control and is developed as the separate entity to encapsulate the predefined color sets initialization code and ListBox and ComboBox controls templates.

The KnownColorPicker control has two sets of predefined colors. The first one contains 64 colors which we can see in the Windows Common Color Dialog. This set is labeled as "Base Colors" and is presented in the ListBox at the top. The second one contains all the colors defined in the Windows.System.Windows.Media.Colors class. This set is labeled as "All WellKnown Colors" and is presented in the ComboBox at the bottom.

That is the sample:

At the figure above the Bisque border is given to the KnownColorPicker control just to make it distinctive.

The KnownColorPicker has the SelectedColor Dependency Property used to get or set the value of the Color selected. When the SelectedColor changes the KnownColorPicker raises the SelectedColorChanged event.

The code

You can download the code and the samples here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/WPFGears/WPFGears.zip

The archive contains my WPFGears library with samples, tests, etc. It’s the Visual Studio 2008 SP1 solution targeted to .NET Framework 3.5.

You’ll find KnownColorPickerSample project there. KnownColorPicker control code is in the WPFGears library project ColorPickerControls folder.

Regards,
Oleg V. Polikarpotchkin

Technorati Теги: ,,
Posted in Uncategorized | Leave a comment

RainbowColorPicker2 Control

The RainbowColorPicker2 control is the composition of the RainbowSlider and the ColorSaturationBox controls. The RainbowColorPicker2 is full fledged color picker allowing you to select the color Hue with its RainbowSlider and the color Saturation and Luminosity with the ColorSaturationBox part.

That is the sample:

At the figure above the Bisque border is given to the RainbowColorPicker2 control just to make it distinctive.

The RainbowColorPicker2 has the SelectedColor Dependency Property used to get or set the value of the Color selected. When the SelectedColor changes the RainbowColorPicker2 raises the SelectedColorChanged event.

The code

You can download the code and the samples here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/WPFGears/WPFGears.zip

The archive contains my WPFGears library with samples, tests, etc. It’s the Visual Studio 2008 SP1 solution targeted to .NET Framework 3.5.

You’ll find RainbowColorPicker2Sample project there. RainbowColorPicker2 control code is in the WPFGears library project ColorPickerControls folder.

Regards,
Oleg V. Polikarpotchkin

Technorati Теги: ,,
Posted in Uncategorized | Leave a comment

RainbowColorPicker Control

This element is the one more control from the ColorPicker constituent controls bug in addition to the published in my recent posts.

The RainbowColorPicker control is the composition of the RainbowBox and the LuminositySlider controls. The RainbowColorPicker is full fledged color picker allowing you to select the color Hue and Saturation with its RainbowBox and the color Luminosity with the LuminositySlider part.

That is the sample:

At the figure above the Bisque border is given to the RainbowColorPicker control just to make it distinctive.

The RainbowColorPicker has the SelectedColor Dependency Property used to get or set the value of the Color selected. When the SelectedColor changes the RainbowColorPicker raises the SelectedColorChanged event.

The code

You can download the code and the samples here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/WPFGears/WPFGears.zip

The archive contains my WPFGears library with samples, tests, etc. It’s the Visual Studio 2008 SP1 solution targeted to .NET Framework 3.5.

You’ll find RainbowColorPickerSample project there. RainbowColorPicker control code is in the WPFGears library project ColorPickerControls folder.

Regards,
Oleg V. Polikarpotchkin

Technorati Теги: ,,
Posted in Uncategorized | Leave a comment