2

I want to make a radio button such that when the button receives focus, it becomes selected. I have an example of what I am trying to achieve:

<Style x:Key="RadioStyle" TargetType="RadioButton">
    <Setter Property="IsChecked" Value="{Binding MyBoolean, Mode=TwoWay}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RadioButton">
                <Border Name="RadioBorder"
                        Margin="4">
                    <ContentPresenter/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="RadioBorder" Property="Background" Value="Red"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="IsChecked" Value="True"/>
        </Trigger>
    </Style.Triggers>
</Style>

The problem:

When MyBoolean is changed in the view model, the radio button becomes selected as it should. When I click or tab onto the radio button, MyBoolean is unchanged. If I remove the style trigger, the problem goes away however I need the ability to select with focus.

Coder1095
  • 828
  • 10
  • 25
  • Have you tried setting the Binding Mode to two-way? – Bob. Sep 10 '12 at 16:35
  • Hi Bob thanks for the quick response. Unfortunately setting the binding mode to two-way doesn't work. It seems that if IsChecked is set when I create the radio button then the style is unable to change it. This is true if I don't use a binding and just use IsChecked=True for example. – Coder1095 Sep 10 '12 at 17:45
  • Have you had a look at [this question](http://stackoverflow.com/questions/2284752/mvvm-binding-radio-buttons-to-a-view-model?rq=1), it looks to be a similar problem. – Bob. Sep 10 '12 at 18:01
  • I just have to say that setting IsChecked when IsFocused is true is a real good way to get in trouble with the user. Imagine trying to tab to the control using the keyboard and having it automatically select. This is against general UI guidelines. – Joel Lucsy Sep 10 '12 at 18:02
  • I haven't described the program in full, but I think this is the best approach. Basically I'm using a list of restyled radio buttons instead of a listbox so that I can make my selection by tabbing, and can also tab onto other components between consecutive items in the list. – Coder1095 Sep 10 '12 at 18:32

1 Answers1

1

I have reproduced your problem. But everything works fine.

The problem may be that the GroupName property of the radio button is not defined. Give a same name for the GroupName of the two radio buttons.

Ex:

<RadioButton Content="No" GroupName="group1" />
<RadioButton Content="Yes" GroupName="group1" />

This is my full XAML:

<Window x:Class="RadioButtonFocus.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        Title="MainWindow" Height="350" Width="525">

    <Grid Name="mainGrid">
        <StackPanel Orientation="Horizontal">

            <RadioButton Content="No" GroupName="group1" IsChecked="{Binding IsNoChecked}">

                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseEnter">
                        <i:InvokeCommandAction Command="{Binding CheckNoCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>

            </RadioButton>

            <RadioButton Content="Yes" GroupName="group1" IsChecked="{Binding IsYesChecked}">

                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseEnter">
                        <i:InvokeCommandAction Command="{Binding CheckYesCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>

            </RadioButton>

        </StackPanel>
    </Grid>
</Window>

ViewModel

public class MainViewModel : ViewModelBase
{
    #region Declarations

    private bool isNoChecked;
    private bool isYesChecked;

    private ICommand checkNoCommand;
    private ICommand checkYesCommand;
    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets a value indicating whether this instance is no checked.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is no checked; otherwise, <c>false</c>.
    /// </value>
    public bool IsNoChecked
    {
        get
        {
            return isNoChecked;
        }
        set
        {
            isNoChecked = value;
            NotifyPropertyChanged("IsNoChecked");
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is yes checked.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is yes checked; otherwise, <c>false</c>.
    /// </value>
    public bool IsYesChecked
    {
        get
        {
            return isYesChecked;
        }
        set
        {
            isYesChecked = value;
            NotifyPropertyChanged("IsYesChecked");
        }
    }

    #endregion

    #region Commands

    /// <summary>
    /// Gets the check no command.
    /// </summary>
    /// <value>The check no command.</value>
    public ICommand CheckNoCommand
    {
        get
        {
            if (checkNoCommand == null)
            {
                checkNoCommand = new RelayCommand(param => this.CheckNo(),
                    null);
            }
            return checkNoCommand;
        }
    }

    /// <summary>
    /// Gets the check yes command.
    /// </summary>
    /// <value>The check yes command.</value>
    public ICommand CheckYesCommand
    {
        get
        {
            if (checkYesCommand == null)
            {
                checkYesCommand = new RelayCommand(param => this.CheckYes(),
                    null);
            }
            return checkYesCommand;
        }
    }

    #endregion

    #region Private Methods

    /// <summary>
    /// Changes the checked.
    /// </summary>
    private void CheckNo()
    {
        this.IsNoChecked = true;
    }

    /// <summary>
    /// Checks the yes.
    /// </summary>
    private void CheckYes()
    {
        this.IsYesChecked = true;
    }

    #endregion
}

NOTE: Here I have used Interactivity library. You have to install a redistributable to work this example. You can download it from here

Haritha
  • 1,498
  • 1
  • 13
  • 35