I have a radio button group in a listview. The rows of this listview (which contain the radio button grp amongst other things) is an observable collection.
the code I have written goes something like this:
The Xaml:
<RadioButton Content="EnumValueName1"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName1}" >
</RadioButton>
<RadioButton Content="EnumValueName2"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName2}">
</RadioButton>
<RadioButton Content="EnumValueName3"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName3}">
</RadioButton>
I am trying to bind directly to the data field called propertyName in my data structure defining the table that holds these values. I do NOT have this field in my ViewModel class for this view. I did this to avoid keeping track of the index of the collection that I am currently populating. (or so i'd like to think!)
The converter:
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 (value == null || 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);
}
}
The problem is that in the ConvertBack function at the Enum.Parse line, the following Argument exception occurs:
Type provided must be an Enum.
Parameter name: enumType
Is there a way to return an enum type to the binding? How do I tell the radio buttons which enumeration value it represents? How do I write a function that returns the appropriate enum value to the binding?
Hoping you guys can help. Thanks in advance!
Try this, it's my version of the EnumToBoolConverter:
public class EnumToBoolConverter : BaseConverterMarkupExtension<object, bool>
{
public override bool Convert(object value, Type targetType, object parameter)
{
if (value == null)
return false;
return value.Equals(Enum.Parse(value.GetType(), (string)parameter, true));
}
public override object ConvertBack(bool value, Type targetType, object parameter)
{
return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
}
}
Ok the solution was relatively simple once I got the concept right. I have done the following which partially solves my problem.
<RadioButton Content="EnumValueName1"
GroupName="RadBtnGrp1"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ParentControl}},
Path=DataContext.propName,
Mode=TwoWay,
Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName1}">
</RadioButton>
The targetType in my ConvertBack function now the correct enum type. Hope this helps!
Now i have to figure out how to make the radiobuttons retain selections in multiple rows of the listview. Presently they a selection in first row deselects the same group from the rest of the rows.
Thank you for your help so far. If anyone can point me to a solution for the new problem that would be really great!
Recommend you to create the radio buttons dynamically, ListBox can help us do that, without converters. The advantage of this method is below:
if someday your enum class changes, you do not need to update the GUI (XAML file).
The steps of this method are below:
create a ListBox and set the ItemsSource for the listbox as the enum and binding the SelectedItem of the ListBox to the selected property.
Then the Radio Buttons for each ListBoxItem will be created.
Step 1: Re-define your Enum.
public enum EnumValueNames
{
EnumValueName1,
EnumValueName2,
EnumValueName3
}
Then add below property to your DataContext (or ViewModel of MVVM), which records the selected item which is checked.
public EnumValueNames SelectedEnumValueName { get; set; }
Step 2: add the enum to static resources for your Window, UserControl or Grid etc.
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type system:Enum}"
x:Key="EnumValueNames">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:EnumValueNames" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Step 3: Use the List Box and Control Template to populate each item inside as Radio button
<ListBox ItemsSource="{Binding Source={StaticResource EnumValueNames}}" SelectedItem="{Binding SelectedEnumValueName, Mode=TwoWay}" >
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<RadioButton
Content="{TemplateBinding ContentPresenter.Content}"
IsChecked="{Binding Path=IsSelected,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
</ListBox>
References:
https://www.codeproject.com/Articles/130137/Binding-TextBlock-ListBox-RadioButtons-to-Enums
Related
There's this combo box in a WPF application that is populated from an enum.
How would one disable some of its items? Disabling has to be dynamic, based on another property in the ViewModel.
<ComboBox ItemsSource="{utility:EnumMarkupExtension {x:Type types:SomeEnum}}"
SelectedItem="{Binding Path=MySelection, Converter={StaticResource SomeEnumToString}}" />
EnumMarkupExtension is defined thus:
public sealed class EnumMarkupExtension : MarkupExtension
{
public Type Type { get; set; }
public EnumMarkupExtension(Type type) => this.Type = type;
public override object ProvideValue(IServiceProvider serviceProvider)
{
string[] names = Enum.GetNames(Type);
string[] values = new string[names.Length];
for (int i = 0; i < names.Length; i++)
values[i] = Resources.ResourceManager.GetString(names[i]);
return values;
}
}
(SomeEnumToString is an IValueConverter which probably is not relevant to this)
Is there some obvious method of doing this that I'm missing?
I've seen solutions like this
https://www.codeproject.com/Tips/687055/Disabling-ComboboxItem-in-ComboBox-Control-using-C
but can't figure out how to pass a property to IValueConverter since ConverterParameter is not bindable.
I know you have solved the issue with the help of #clemens. Still posting an answer for others who might same question.
Assuming VMDataSource is datasource in Viewmodel and with each item in VMDataSource contains a boolean flag to indicate whether to enable/ disable the item. Following code snippet would work as you queried in the post.
<ComboBox ItemsSource="{Binding VMDataSource}">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding Path="VMDisableItem"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Assuming VMDataSource is datasource in Viewmodel and viewmodel contains a Non-boolean property to indicate whether to enable/ disable the item instead of datasource itself containing a bool property to enable/diasble the item(Incase of enums).
In this case a multibinding and a converter that would take the item in VMDataSource and a
non-boolean property to enable/disable an item as follows
<ComboBox DataContext="{StaticResource viewmodelInstance}"
ItemsSource="{Binding VMDataSource}">
<ComboBox.Resources>
<local:Disabler x:Key="disabler"/>
</ComboBox.Resources>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource disabler}">
<!--Here you can bind the proper u want to use in -->
<!--converter to enable/ disable comboboxitem-->
<!--Currently it is bound property of viewmodelInstance that as non-boolean property-->
<Binding
RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=ComboBox}"
Path="DataContext.VMDisableItem"/>
<!--Bind to the current comboboxitem which needs to enabled/disabled-->
<Binding />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Assuming typeof(VMDisableItem) and typeof(VMDataSource) are both string.
When both are equal, disable the item otherwise enable.
class Disabler : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return !Equals(values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You can use a multiBinding where one of the values is instead of the ConverterParameter. See this answer
Edit the comboboxitem itemtemplate, in the item template bind IsEnabled with the value of the viewmodel (it should be an index) and converter paraemeter the value of the item itself.
Today I found something strange (for me). If I want to update a DataGrid through a property in my ViewModel the Binding wont get notified. The special think here is (I think) the Binding is bound to another object (part of an Collection) not directly the property i change.
I have prepared some sample code for you. But first a little (Depper) explanation.
Of course it is just a sample but here I have a ViewModel with two public Properties (Items and CurrentItem). Items is a ObservableCollection and serves as the ItemsSource of my DataGrid. CurrentItem is a String which serves as indicator for a converter to set the background colour (for the grid).
I add two instances o String to my Collection and after the program is started the behaviour is as expected. The first line is green the second is white (set through the converter and the properties).
But if I change the value of CurrentItem after the program was loaded (lets say through the button) the colours wont update on my Datagrid.
If I create a breakpoint at the beginning of the converter I can see (after the loading process) the converter wont execute again so it has to be a Problem with the Binding. I think the problem is my property which is not part of the items in my Collection. The OnPropertyChange method seems to not trigger the update for the RowStyle properly.
In real life the model class of the collections is not a string and the model class implements INotifyPropertyChange (but I don´t think this is the problem cause i just don´t update anything in the model).
I need this kind of behaviour to visible highlight more rows based on a dynamic indicator (similar to the example). If no one knows a better way I think I will implement some kind of Property in my models and update the property with a method from the ViewModel.
ViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
public static MainWindowViewModel instance = null;
private string _CurrentItem;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string Property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(Property));
}
}
public string CurrentItem
{
get
{
return _CurrentItem;
}
set
{
if (value != _CurrentItem)
{
_CurrentItem = value;
OnPropertyChanged("CurrentItem");
OnPropertyChanged("Items");
}
}
}
public ObservableCollection<String> Items { get; set; }
public MainWindowViewModel()
{
instance = this;
Items = new ObservableCollection<string>();
CurrentItem = "First";
Items.Add("First");
Items.Add("Second");
Items.Add("First");
}
View XAML
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<local:StringToColorConverter x:Key="StringToColorConverter" />
</Window.Resources>
<DockPanel Margin="30">
<Button DockPanel.Dock="bottom" Content="From First to Second" Click="Button_Click" />
<DataGrid IsReadOnly="True" ItemsSource="{Binding Items}" ColumnWidth="*" AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background"
Value="{Binding Converter={StaticResource StringToColorConverter}}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Text" Binding="{Binding}" />
</DataGrid.Columns>
</DataGrid>
</DockPanel>
Converter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as string;
if (item == MainWindowViewModel.instance?.CurrentItem)
return "Green";
return "White";
}
So sorry for the long post I hope you can comprehend my problem and of course maybe help me :)
You can involve CurrentItem using an IMultiValueConverter
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiStringToColorConverter}">
<Binding />
<Binding Path="DataContext.CurrentItem"
RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
The Converter
public class MultiStringToColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
var item = values[0] as string;
var current = values[1] as string;
if (item == current)
return new SolidColorBrush(Colors.Green);
return new SolidColorBrush(Colors.White);
}
public object[] ConvertBack(object values, Type[] targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Everything is normal !
It is by design.
Your background is bound to the n-th object of the DataGrid.
It is not bound to CurrentItem, so there is no reason the binding updates the n-th line background.
Because you have an ObservableCollection, you could put a IsSelected property in MyItem class
And you should make MyItem ràise a PropertyChanged event on IsSelected property.
Of course MyItem would implement INotifyPropertyChanged
Last, you should change the binding :
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background"
Value="{Binding Path=IsSelected,
Converter={StaticResource BooleanToColorConverter}}" />
</Style>
</DataGrid.RowStyle>
Of course changing the StringToColorConverter into BooleanToColorConvert wouldbe trivial.
Regards
I have a tabcontrol like this:
<TabControl>
<local:TabItem x:Name="son" Header="son">
<local_son:SonView />
</local:TabItem>
<local:TabItem x:Name="daughter" Header="daughter">
<local_daughter:DaughterView />
</local:TabItem>
</TabControl>
There is a button in DaughterView, I want to click this button to switch to
son tab. My questions is how can I reach to tabindex of son tab in the DaughterView?
Thank you in advance!
Seems kinda odd to have a button inside of a tab switch to another tab. I would think that would be a toolbar button or something like that. I.e. outside of the tab. But if you insist :)... I'd use the messenger / event aggregator pattern and post an event and have the view subscribe and switch the tab. I wouldn't have the child view do it byitself.
You need to bind "SelectedIndex" to a property in your view model. I personally like keeping things type-safe and able to be unit-tested, so when I need to manipulate TabControls in code I usually start by declaring an enum with one value for each tab:
public enum MyTabs : int
{
[Description("Tab 1")]
Tab1,
[Description("Tab 2")]
Tab2,
[Description("Tab 3")]
Tab3
}
The description attribute is the text I want displayed in the tab header, more on that in a moment. My view model contains a member of type MyTabs which is updated whenever the user clicks a tab and which I can also set manually myself via code:
public class MyViewModel : ViewModelBase
{
private MyTabs _CurrentTab;
public MyTabs CurrentTab
{
get { return this._CurrentTab;}
set { this._CurrentTab = value; RaisePropertyChanged(() => this.CurrentTab); }
}
}
Now you need to bind your TabControl to this property:
<TabControl
ItemsSource="{Binding Source={StaticResource MyTabs}}"
SelectedIndex="{Binding CurrentTab, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Path=., Converter={StaticResource EnumDescriptionConverter}}" />
</Style>
</TabControl.Resources>
</TabControl>
Unfortunately WPF binding isn't smart enough to work with integer enums, so I'm also using a converter to cast between enums and integers:
public class EnumToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.ToObject(targetType, value);
}
}
There are a few other things going on here...first of all you'll notice that I'm not actually declaring the TabItems anywhere. That's because I'm generating them automatically from the Enum values themselves; if I add a new value to the MyTab enum then a tab for it magically appears! In this case I'm binding to a static resource with the key "MyTabs", that's a ObjectDataProvider that enumerates the values in my enum:
<ObjectDataProvider x:Key="MyTabs" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:MyTabs"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
This raises the question of how the tabs know what to display in their headers and on the tabitem content areas. The headers use the "Description" attribute declared in the enum, the code for the EnumDescriptionConverter is on another page on this site. To specify the content for each page I create a ControlTemplate for each of my enum values and key it to the enum value itself. A data template is then used to select the appropriate one to use for each tab:
<Window.Resources>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab1}">
<TextBlock Text="This is the first tab" />
</ControlTemplate>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab2}">
<TextBlock Text="This is the second tab" />
</ControlTemplate>
<ControlTemplate x:Key="{x:Static local:MyTabs.Tab3}">
<TextBlock Text="This is the third tab" />
</ControlTemplate>
<DataTemplate DataType="{x:Type local:MyTabs}">
<ContentControl>
<ContentControl.Template>
<MultiBinding Converter="{StaticResource ResourceKey=BindingToResourceConverter}">
<Binding RelativeSource="{RelativeSource AncestorType={x:Type Window}}" Path="Resources" />
<Binding />
</MultiBinding>
</ContentControl.Template>
</ContentControl>
</DataTemplate>
</Window.Resources>
The final piece of the puzzle is the BindingToResourceConverter which simply takes a binding (i.e. one of the enum values) and uses it to look up the appropriate ControlTemplate:
public class BindingToResourceConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (values[0] as ResourceDictionary)[values[1]];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And that's it! Every time I want to add a new page to a TabControl I simply add a value to it's corresponding enum and create a ContentControl key'd to that value. Everything else happens automatically, and best of all it's both type-safe and unit-testable.
How can I bind an inverted value of a bool in my xaml?
I know, I know, there are a lot of q&a about this, but there aren't any about a specific case: when the converter is in a view model and the radio button in a user control.
how can I correctly refer to the main window view model data context? In other case I used the code I've posted, but in this case I don't get how to use it.
UPDATE CODE:
namespace ***.ViewModel
{
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
class MainWindowViewModel : MyClass.UtilityClasses.ViewModelBase
{
public MainWindowViewModel(){
SaveCommand = new DelegateCommand(SaveData, CanSave );
UndoCommand = new DelegateCommand(UndoActions, CanSave);
[...]
}
....
}
ANOTHER CODE UPDATE:
In my xaml, I have a devexpress GridControl where I list my observableCollection from db. When I click one element, a layout group is populated with the relative data.
In this layout group, I have:
<StackPanel Margin="0" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<RadioButton Content="{DynamicResource Locale}" Margin="10,0,0,0" x:Name="rd_LOCALE" VerticalAlignment="Center" IsChecked="{Binding Path=REMOTO, Converter={StaticResource InverseBooleanConverter}}" GroupName="Location" Panel.ZIndex="9" TabIndex="10" />
<RadioButton Content="{DynamicResource Remoto}" Margin="10,0,6,0" x:Name="rd_REMOTO" VerticalAlignment="Center" IsChecked="{Binding REMOTO}" GroupName="Location" Panel.ZIndex="10" TabIndex="11" Tag="PRISMA" />
</StackPanel>
WhenI change from one record to another, the converter gives me error... why? It fails the "if (targetType != typeof(bool))" row. So I tried to change that like:
if (value.getType() != typeof(bool))
but in this way, without fails nothing in the code, it put the wrong value in the radiobutton!
You need to make sure that the value converter is referenced in the XAML
<UserControl.Resources>
<myproject:InverseBooleanConverter x:Key="InverseBooleanConverter" />
</UserControl.Resources>
where my project is the namespace in which the value converter class is defined
I'm using the following control template in two windows that are opened at the same time and both using the SAME viewmodel.
Here is the template;
<ControlTemplate x:Key="SecurityTypeSelectionTemplate">
<StackPanel>
<RadioButton GroupName ="SecurityType" Content="Equity"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumBoolConverter}, ConverterParameter=Equity}" />
<RadioButton GroupName ="SecurityType" Content="Fixed Income"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumBoolConverter}, ConverterParameter=FixedIncome}" />
<RadioButton GroupName ="SecurityType" Content="Futures"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumBoolConverter}, ConverterParameter=Futures}" />
</StackPanel>
</ControlTemplate>
Here is the viewmodel property:
private SecurityTypeEnum _securityType;
public SecurityTypeEnum SecurityType
{
get { return _securityType; }
set
{
_securityType = value; RaisePropertyChanged("SecurityType");
}
}
Here's the Enum:
public enum SecurityType { Equity, FixedIncome, Futures }
Here is the converter:
public class EnumToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object enumTarget, CultureInfo culture)
{
string enumTargetStr = enumTarget as string;
if (string.IsNullOrEmpty(enumTargetStr))
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object expectedEnum = Enum.Parse(value.GetType(), enumTargetStr);
return expectedEnum.Equals(value);
}
public object ConvertBack(object value, Type targetType, object enumTarget, CultureInfo culture)
{
string expectedEnumStr = enumTarget as string;
if (expectedEnumStr == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, expectedEnumStr);
}
}
The problem is a bit strange. I have two windows that are showing slightly different views of the SAME ViewModel. The same template shown above is reused in both views.
If Equity is initially set as SecurityType, i can change this to FixedIncome by clicking on the relevant radio button. I can not then change it back to Equity.
I can however set it to Futures. But then after that, i can not change it to either FixedIncome or Equity by clicking the relevant radio buttons.
What's happening in the cases where i can not set change it back is that the Setter is called twice. the first time it's setting the value to the correct selected value, but the moment RaisePropertyChanged is fired,
the setter is invoked again, this time with the original value.
It feels like when RaisePropertyChanged, the the setter is being called by the binding from the 2nd window, thus overwriting the value being set in the first window where the user makes the selection.
Does anyone know if this is the case and how to avoid in this scenario?
Here's my version of EnumToBoolConverter:
public class EnumToBoolConverter : BaseConverterMarkupExtension<object, bool>
{
public override bool Convert(object value, Type targetType, object parameter)
{
if (value == null)
return false;
return value.Equals(Enum.Parse(value.GetType(), (string)parameter, true));
}
public override object ConvertBack(bool value, Type targetType, object parameter)
{
return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
}
}
The default behavior for a RadioButton is to update the source when the property changes so both windows are trying to update the source. One fix is to only update the source only from where the user clicked. To do this use Binding.UpdateSourceTrigger Explict on the binding. Add a click handler in code behind for RadioButton. In it explicity update the source.
<StackPanel>
<RadioButton GroupName ="SecurityType" Content="Equity"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, UpdateSourceTrigger=Explicit, ConverterParameter=Equity}" Click="RadioButton_Click" />
<RadioButton GroupName ="SecurityType" Content="Fixed Income"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, UpdateSourceTrigger=Explicit, ConverterParameter=FixedIncome}" Click="RadioButton_Click"/>
<RadioButton GroupName ="SecurityType" Content="Futures"
IsChecked="{Binding Path=SecurityType, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, UpdateSourceTrigger=Explicit, ConverterParameter=Futures}" Click="RadioButton_Click"/>
</StackPanel>
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
BindingExpression be = ((RadioButton)sender).GetBindingExpression(RadioButton.IsCheckedProperty);
be.UpdateSource();
}
You may have to use a UserControl instead of or inside your ControlTemplate to get code behind in your view.