Mvvm: Binding Radio Buttons to a View Model

WPF + MVVM + RadioButton : Handle binding with single property

You need a converter.

//define this in the Window's Resources section or something similiarly suitable
<local:GenderConverter x:Key="genderConverterKey" />

<RadioButton Content="M" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=M}" />
<RadioButton Content="F" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=F}" />

The converter

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

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool)value ? parameter : null;
}
}

Replace null (in ConvertBack) with Binding.DoNothing if binding should not be applied in that case.

return (bool)value ? parameter : Binding.DoNothing;

MVVM: Binding radio buttons to a view model?

If you start with Jason's suggestion then the problem becomes a single bound selection from a list which translates very nicely to a ListBox. At that point it's trivial to apply styling to a ListBox control so that it shows up as a RadioButton list.

<ListBox ItemsSource="{Binding ...}" SelectedItem="{Binding ...}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

What is the proper way to bind a radio button in MVVM / MVVM Light

You can bind the name of the RadioButton. By the name received in the method, you can your right action.

XAML

<RadioButton x:Name="radioButton1" 
Content="RadioButton1"
IsChecked="True"
Command="{Binding RadioButtonCommand }" CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource Self}}"/>

<RadioButton x:Name="radioButton2"
Content="RadioButton2"
IsChecked="True"
Command="{Binding RadioButtonCommand }" CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource Self}}"/>

ViewModel

public RelayCommand<string> RadioButtonCommand { get; }

public MyClassConstructorViewModel()
{
RadioButtonCommand = new RelayCommand<string>(radioButtonClick);
}

private void radioButtonClick(string name)
{
if(name == "radioButton1")
Console.WriteLine("Radio Button 1 Clicked...");
else if(name == "radioButton2")
Console.WriteLine("Radio Button 2 Clicked...");
}

Radio Button Binding MVVM Application

I'd recommend you to use the ListBox method instead of the one you mentioned. You may find it here:

http://www.codeproject.com/Tips/807025/WPF-MVVM-Binding-for-Multiple-Radio-Buttons



If you'd like to keep the "abstract" groups (custom and standard style architecture modeling), then one of the solution that comes to my mind now is to implement a TextBox in the ControlTemplate and bind it to a property on the view model.

    <ListBox ItemsSource="{Binding RadioCollection}" SelectedItem="{Binding SelectedRadio}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<TextBlock Text="{Binding AbstractGroupHeader}" />
<RadioButton
Content="{Binding Header}" ToolTip="{Binding ToolTip}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="5"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

The view model basically is responsible for the view's state (e.g. an animation on the view isn't definied in the view model, but the view model may release, as in start it). VM is a class that you define and it must implement INotifyPropertyChanged interface found in namespace System.ComponentModel in case you want the view to be notified when you change property's value in code. Keep in mind, that the property must have a public access modifier, in order for the binding to work. If you want to follow this method, then read the article located under the link I gave. However, if you want a simpler solution, which will work with your code, then you have to bind IsChecked dependency property of each of the radio buttons to appropriate properties on the view model, like this:

    <RadioButton Content="Pipeline and Filter Architecture Modeling" 
Margin="50 0 10 0" GroupName="Standard" IsChecked="{Binding IsPipelinedModeling}"/>

And the VM in this case would look like this:

public class SettingsViewModel : INotifyPropertyChanged
{
bool _isPipelinedModeling;
public bool IsPipelinedModeling
{
get { return _isPipelinedModeling; }
set
{
if (_isPipelinedModeling == value)
return;
_isPipelinedModeling = value;
RaisePropertyChanged();
}
}

#region INotifyPropertyChanged implementation

public void RaisePropertyChanged([CallerMemberName]string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

public event PropertyChangedEventHandler PropertyChanged;

#endregion INotifyPropertyChanged implementation
}

To bind the view model to the view you can use either "view first" or "view model first" approach. I'm using view first. In the constructor of the window, user control or whatever you're using, add the following code:
this.Loaded += (s, e) =>
{
this.DataContext = new SettingsViewModel();
};
The code creates a new view model object and sets it as the window's DataContext.

Binding to a button is a little bit different though, because you have to declare a command. It is a class of your own, implementing ICommand interface:

    ICommand _drawModelingArchitectureCommand;
public ICommand DrawModelingArchitectureCommand
{
get
{
return _drawModelingArchitectureCommand ?? (_drawModelingArchitectureCommand = new DrawTheModelingArchitectureCommand());
}
}

public class DrawTheModelingArchitectureCommand : ICommand
{
public bool CanExecute(object parameter)
{
// the code that decides whether the button will be enabled or not
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
// the code that is executed when the button is pressed
}
}

And finally the XAML for the button:

    <Button Grid.Row="1" Content="Let's Go Draw It..." VerticalAlignment="Bottom" HorizontalAlignment="Center" Command="{Binding DrawTheModelingArchitecture}"/>

C# MVVM: Binding a RadioButton to a boolean Property

Just bind HybridSeed to the Yes-radiobutton. It will then either be true if the user has selected that or false if No-radiobutton has been selected (or if nothing has been selected). Binding to both buttons in this case is a bit redundant since the mechanism of radiobuttons takes care of it.

WPF:

<RadioButton Content="Yes" IsChecked="{Binding HybridSeed}" />
<RadioButton Content="No" />
<Label Content="{Binding HybridSeed}" ContentStringFormat="Value is: {0}" />

Logic:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}

public class ViewModel : INotifyPropertyChanged
{
private bool hybridSeed;

public bool HybridSeed
{
get { return hybridSeed; }
set
{
hybridSeed = value;
OnPropertyChanged(nameof(HybridSeed));
}
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

MVVM radiobuttons

Take a look here.

I haven't implemented the solution provided but it makes sense. The underlying framework control breaks you bindings when a click is performed. The solution is to override the method that does this and just rely on the bindings.

How to add event on radio button change with MVVM pattern?

You typically use commands to handle events in a MVVM application. Please refer to this blog post for more information about this.

Once you have added a command to your SelectableItem class that displays the MessageBox, you could bind the Command property of the RadioButton to this source property:

<RadioButton GroupName="Salads"
Content="{Binding ItemDescription}"
IsChecked="{Binding IsSelected}"
Command="{Binding YourCommand}"
Margin="5,1"/>

The command will then be invoked when you check or uncheck the RadioButton.

MVVM Keeping track of selected Radio Button

I solved this by using this approach MVVM: Binding radio buttons to a view model? and binding the SelectedItem property with the value of the selected radio button.

The selected radio button is kept track on one of the fields of my observable collection CurrentQuestion.StudentAnswer.

MVVM: Binding radio buttons to a view model?

If you start with Jason's suggestion then the problem becomes a single bound selection from a list which translates very nicely to a ListBox. At that point it's trivial to apply styling to a ListBox control so that it shows up as a RadioButton list.

<ListBox ItemsSource="{Binding ...}" SelectedItem="{Binding ...}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>


Related Topics



Leave a reply



Submit