RadioButtonのチェックがコードからCheckできなくなるバグはWPF4でも未だ直っていないようだ。
このバグは以下のコードで再現される。
<Window x:Class="test2010wpf.RadioButtonTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:test2010wpf" Title="RadioButtonTest" Height="150" Width="502"> <Window.Resources> <local:BoolToByteConverter x:Key="boolToByteConverter" /> </Window.Resources> <Grid> <StackPanel Margin="0,0,0,51"> <RadioButton Content="RadioButton1" Height="16" Name="radioButton1" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=1}" /> <RadioButton Content="RadioButton2" Height="16" Name="radioButton2" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=2}"/> <RadioButton Content="RadioButton3" Height="16" Name="radioButton3" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=3}" /> </StackPanel> <Button Content="Select RadioButton1" Height="23" HorizontalAlignment="Left" Margin="0,76,0,0" Name="button1" VerticalAlignment="Top" Width="132" Click="button1_Click" /> <Button Content="Select RadioButton2" Height="23" HorizontalAlignment="Left" Margin="147,76,0,0" Name="button2" VerticalAlignment="Top" Width="132" Click="button2_Click" /> <Button Content="Select RadioButton3" Height="23" HorizontalAlignment="Left" Margin="294,76,0,0" Name="button3" VerticalAlignment="Top" Width="132" Click="button3_Click" /> </Grid> </Window>
using System; using System.Windows; using System.Windows.Data; using System.Globalization; namespace test2010wpf { /// <summary> /// RadioButtonTest.xaml の相互作用ロジック /// </summary> public partial class RadioButtonTest : Window { public RadioButtonTest() { InitializeComponent(); this.DataContext = this; } // Dependency Property public static readonly DependencyProperty OptionTypeProperty = DependencyProperty.Register("OptionType", typeof(byte), typeof(RadioButtonTest)); // CLR Property Wrapper public byte OptionType { get { return (byte)GetValue(OptionTypeProperty); } set { SetValue(OptionTypeProperty, value); } } private void button1_Click(object sender, RoutedEventArgs e) { OptionType = 1; } private void button2_Click(object sender, RoutedEventArgs e) { OptionType = 2; } private void button3_Click(object sender, RoutedEventArgs e) { OptionType = 3; } } public class BoolToByteConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var v = (byte)value; if (v == byte.Parse(parameter.ToString())) return true; else return false; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return parameter; } } }
この画面でRadioButtonにチェックするために適当に「Select RadioButton1」、「Select RadioButton2」、「Select RadioButton3」を押していくと、
やがてそれらのボタンを押してもRadioButtonが反応しなくなる。これについては以下によればバグであり、WPF 4で既に修正されているとのことであるが、
私が試した限り、WPF 4でも修正されていない。
RadioButton unchecked bindings issue still not resolved? http://social.msdn.microsoft.com/forums/en-US/wpf/thread/8eb8280a-19c4-4502-8260-f74633a9e2f2/
このバグの対処としては、上記のリンク先に書いてある通り、異なるGroupNameを付ければ良い。つまり、以下のようにすれば良い。
<RadioButton Content="RadioButton1" Height="16" Name="radioButton1" GroupName="a" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=1}" /> <RadioButton Content="RadioButton2" Height="16" Name="radioButton2" GroupName="b" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=2}"/> <RadioButton Content="RadioButton3" Height="16" Name="radioButton3" GroupName="c" IsChecked="{Binding OptionType, Converter={StaticResource boolToByteConverter}, ConverterParameter=3}" />
しかし、上記の対処方法は、StackPanelを使わずにGroupNameを同じにすることによって3つのRadioButtonをグルーピングしている場合には使用できない。この場合の対処方法はいろいろ試した結果見つけたのであるが、以下のようにどのRadioButtonも取りえない値を一度セットすれば良いようだ。原因も何故うまく動くのかもわからなので保障はしませんがw
private void button1_Click(object sender, RoutedEventArgs e) { OptionType = 255; OptionType = 1; } private void button2_Click(object sender, RoutedEventArgs e) { OptionType = 255; OptionType = 2; } private void button3_Click(object sender, RoutedEventArgs e) { OptionType = 255; OptionType = 3; }