I have an application with four radio buttons to select the mode I am operating.
All the 4 Radio Buttons are binded to the same property. When i start the program the none of the radio button is checked.
This is the code for the radio buttons:
<GroupBox Grid.Row="0" Margin="10,10,10,10" FontSize="16"
FontWeight="Bold">
<GroupBox.Header>Tipo di Rientro</GroupBox.Header>
<StackPanel>
<RadioButton Name="RdBtnExternalEntry" FontSize="12"
FontWeight="Normal" GroupName="SelectionType" IsChecked="{Binding
Path=CurrentOption, Mode=TwoWay, Converter={StaticResource
enumConverter}, ConverterParameter=ExternalEntry}">Entrata da
Esterno</RadioButton>
<RadioButton Name="RdBtnEntryAfterCheck" FontSize="12"
FontWeight="Normal" GroupName="SelectionType" IsChecked="{Binding
Path=CurrentOption, Mode=TwoWay, Converter={StaticResource
enumConverter}, ConverterParameter=EntryAfterCheck}">Rientro dopo
visione</RadioButton>
<RadioButton Name="RdBtnEntryMissingShipping" FontSize="12"
FontWeight="Normal" GroupName="SelectionType" IsChecked="{Binding
Path=CurrentOption, Mode=TwoWay, Converter={StaticResource
enumConverter}, ConverterParameter=EntryMissingShipping}">Rientro
per mancata Spedizione</RadioButton>
<RadioButton Name="RdBtnEntryAfterPicking" FontSize="12"
FontWeight="Normal" GroupName="SelectionType" IsChecked="{Binding
Path=CurrentOption, Mode=TwoWay, Converter={StaticResource
enumConverter}, ConverterParameter=EntryAfterPicking}">Rientro
dopo Picking</RadioButton>
</StackPanel>
</GroupBox>
This is the property:
public RadioOptions CurrentOption
{
get => _currentOption;
set
{
_currentOption = value;
NewLoadCommand.RaiseCanExecuteChanged();
ConfirmCommand.RaiseCanExecuteChanged();
if (value == RadioOptions.ExternalEntry)
{
_selectedStockUnitCode = PalletToDo;
SelectedLoadnumber = LoadToDo;
RaisePropertyChanged("SelectedLoadnumber");
RaisePropertyChanged("SelectedStockUnitCode");
}
else
{
SelectedLoadnumber = "0";
RaisePropertyChanged("SelectedLoadnumber");
}
RaisePropertyChanged("SelectedStockUnitCodeIsEnabled");
RaisePropertyChanged("SelectedLoadnumberIsEnabled");
}
}
And this is the converter:
public class EnumMatchToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
return false;
string checkValue = value.ToString();
string targetValue = parameter.ToString();
return checkValue.Equals(targetValue,
StringComparison.InvariantCultureIgnoreCase);
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
return null;
bool useValue = (bool)value;
string targetValue = parameter.ToString();
if (useValue)
return Enum.Parse(targetType, targetValue);
return Binding.DoNothing;
}
}
these are the radio options:
public enum RadioOptions { ExternalEntry, EntryAfterCheck, EntryMissingShipping, EntryAfterPicking }
I expect the first combobox to be checked at the start of the program
Resolved! I was, by mistake launching another copy of my window as a popup istance messing up with the way xaml manages the radio buttons. I deleted one of the istance and then it worked fine.
Related
I am trying to create a re-usable user control (for data entry) in which there are two text boxes and they are linked to each by an IValueConvertor.
The following XAML is the original, normal code. This is what I am trying to reproduce in a user control.
<WrapPanel>
<TextBlock Text="Length of Fence"/>
<TextBox Name="Metric" Width="50" Text="{Binding Path=LengthFence, Mode=TwoWay}"/>
<TextBlock Text="Meters"/>
<TextBox Text="{Binding ElementName=Metric, Path=Text, Converter={StaticResource MetersToInches}, StringFormat=N8}"/>
<TextBlock Text="Inches"/>
</WrapPanel>
and the code-behind for the IValueConvertor (in MainWindow.xaml) is
public class MetersToInches : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.ToString() == "")
return 0.0;
try
{
double meters = System.Convert.ToDouble(value);
var result = meters * 39.3701;
return result;
}
catch
{
// Catch errors when users type invalid expressions.
return 0.0;
}
}
public object ConvertBack(object value, Type targettype, object parameter, CultureInfo culture)
{
if (value.ToString() == "")
return 0.0;
try
{
double inches = System.Convert.ToDouble(value);
var result = inches * 0.0254;
return result;
}
catch
{
// Catch errors when users type invalid expressions.
return 0.0;
}
}
}
This is what this XAML looks like:
Now I have made a re-usable UserControl with three dependency properties Label for label string, Value for binding a property inside the ViewModel, and Units - a string property to show the input units.
<UserControl ...
x:Name="parent">
<StackPanel DataContext="{Binding ElementName=parent}">
<TextBlock Text="{Binding Path=Label}"/>
<TextBox Text="{Binding Path=Value}"/>
<TextBlock Text="{Binding Path=Units}"/>
</StackPanel>
However, this re-usable control can only tackle the first TextBox of the input. I do not know how to bind the IValueConvertor in the second TextBox. I need to do this because I want to bind other converters such as meters to feet, kg to pound, etc.
I have read that ConvertorParameter cannot be bound because it is not a dependency property and I am not sure if I can use multi-binding, mostly because I do not know how to use it properly Binding ConverterParameter.
I would be very grateful if you could show me how to do this or direct me to the appropriate link on StackOverflow or elsewhere that solves this problem. Or if there is a better way of doing this.
Many many thanks in advance.
First, don't bind the TextBoxes to each other (as in your original code at the begining of the question), instead, bind each TextBox to the same backing property, which, in your UserControl, is Value.
As for how to implement multiple bindings, you probably don't need a MultiBinding.
We have to pick a "standard" unit of measure to begin with- this will be the unit that will be actually stored in the property and in any database or file. I'll assume this standard unit will be meters (m). An IValueConverter can be used to convert between meters and some other unit of distance and back, using the ConverterParameter to specify which other unit to convert to/from.
Here's a good example to get you started.
public enum DistanceUnit { Meter, Foot, Inch, }
public class DistanceUnitConverter : IValueConverter
{
private static Dictionary<DistanceUnit, double> conversions = new Dictionary<DistanceUnit, double>
{
{ DistanceUnit.Meter, 1 },
{ DistanceUnit.Foot, 3.28084 },
{ DistanceUnit.Inch, 39.37008 }
};
//Converts a meter into another unit
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return conversions[(DistanceUnit)parameter] * (double)value;
}
//Converts some unit into a meter
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) { return 0; }
double v;
var s = value as string;
if (s == null)
{
v = (double)value;
}
else
{
if (s == string.Empty) { return 0; }
v = double.Parse(s);
}
if (v == 0) { return 0; }
return v / conversions[((DistanceUnit)parameter)];
}
}
The above has a few problems. I never check if parameter really is a DistanceUnit before using it, for example. But it works.
Here's an example of how I used it:
<StackPanel>
<StackPanel.Resources>
<local:DistanceUnitConverter x:Key="DistCon"/>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Distance, Converter={StaticResource DistCon}, ConverterParameter={x:Static local:DistanceUnit.Meter}}" MinWidth="20"/>
<TextBlock>m</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Distance, Converter={StaticResource DistCon}, ConverterParameter={x:Static local:DistanceUnit.Foot}}" MinWidth="20"/>
<TextBlock>ft</TextBlock>
</StackPanel>
</StackPanel>
The DistanceUnit enum and the internal conversions dictionary can be expanded with more units of measure. Alternatively, you can use a 3rd party library that already has all these included, like UnitsNet.
Not sure how you would like to bind mulitple converters in one single control. If i'm not wrong, you would like to build a control where when a user enters a particular value, you need to display it in different units. If this is the case, you can create a single converter with converterparameter as "m","cm","inch" etc and based on this you can return the result. Then in this case, you will have 4,5 controls and each will have same converter binding but different converter values. If this is not clear and you need further direction, please let know.
Multi Value binding
To answer your point 6, please see a sample multi binding converter and its implementation in xaml below. I have built a simple RolesFilter which will take different inputs from the xaml as object[] and since I already know what data is expected, i'm converting them in the converter.
public class RolesFilter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
try
{
FlipperObservableCollection<Role> _roles = (FlipperObservableCollection<Role>)values[0]; //Input
Department _dept_param = values[1] as Department;
bool _filter = (bool)values[2];
string _id = "NA";
if (values.Count() == 4 && values[3] is string) _id = (string)values[3] ?? "NA";
//If we need a filter, then without department, it should return empty results
if (!_filter) return _roles; //If no filter is required, then don't worry, go ahead with input values.
if (_dept_param == null) return new FlipperObservableCollection<Role>(); //If department is null, then
List<Role> _filtered_list = _roles.ToList().Where(p => p.department.id == _dept_param.id && p.id != _id)?.ToList() ?? new List<Role>();
return new FlipperObservableCollection<Role>(_filtered_list);
}
catch (Exception)
{
throw;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I'm using the multi value converter in the xaml as below. Here, i'm filtering an itemsource of a combo box based on another combobox and a check box. This is just an example and in your case, you can create a combo box with different Units values. Based on user selection, you can use the converter and return value to the textbox.
<ComboBox Height="30" SelectedItem="{Binding reports_to, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource roles_filter}">
<Binding Source="{StaticResource SingletonData__}" Path="roles" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="department" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding ElementName="cbx_filter" Path="IsChecked"/>
<Binding Path="id" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding department.name}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding name}"/>
</WrapPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I'm developing a small application that needs to check some availability properties. I'm using for the user interface WPF. I need to change some foreground colors if a selection from a combobox. I have this DataTemplate:
<DataTemplate x:Key="userTemplate">
<TextBlock VerticalAlignment="Center">
<Image Source="imgsource.png" Height="25" Width="25" />
<Run Text="{Binding BooleanObjectName}" Foreground="{Binding boolobject, Converter={StaticResource convAvailability}}"/>
</TextBlock>
So I'm using for this convertion a IValueConverter that sets the color to the foreground:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BooleanObject boolobject = (BooleanObject)value;
if (boolobject.IsBoolValueOne) return System.Drawing.Brushes.Green;
else if (boolobject.IsBoolValueTwo) return System.Drawing.Brushes.Red;
else if (boolobject.IsBoolValueThree) return (SolidColorBrush)(new BrushConverter().ConvertFrom("#d3d300"));
else return System.Drawing.Brushes.Black;
}
What is wrong with this, because in my interface I'm always getting the black color. Any thoughts on this ?
Any help would be very much appreciated.
Thanks in advance.
As pointed out by #Funk you return the wrong kind of brushes. You should return a System.Windows.Media.Brush object:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BooleanObject boolobject = (BooleanObject)value;
if (boolobject.IsBoolValueOne)
return System.Windows.Media.Brushes.Green;
else if (boolobject.IsBoolValueTwo)
return System.Windows.Media.Brushes.Red;
else if (boolobject.IsBoolValueThree)
return (SolidColorBrush)(new BrushConverter().ConvertFrom("#d3d300"));
return System.Windows.Media.Brushes.Black;
}
Then it should work provided that your binding to the boolobject property actually works. Otherwise your converter won't get invoked at all.
If you want to bind to the object itself, you should specify a path of '.':
<TextBlock VerticalAlignment="Center">
<Image Source="imgsource.png" Height="25" Width="25" />
<Run Text="{Binding BooleanObjectName}" Foreground="{Binding Path=., Converter={StaticResource convAvailability}}"/>
</TextBlock>
I am new in WPF I want validate my IP address but I have a problem: when I try to show the error message, it shows me only an empty red border.
Here is the ControlTemplate and all the code:
<Window x:Class="SOTCBindingValidation.Window1"
x:Name="This"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SOTCBindingValidation"
Title="SOTC Validation Test" Height="150" Width="400">
<Window.Resources>
<local:ErrorsToMessageConverter x:Key="eToMConverter"/>
<ControlTemplate x:Key="customvalidatortemplate">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="Red" VerticalAlignment="Top">
<Grid>
<AdornedElementPlaceholder x:Name="adorner" Margin="-1"/>
</Grid>
</Border>
<Border x:Name="errorBorder" Background="Red" Margin="8,0,0,0"
CornerRadius="0" IsHitTestVisible="False">
<TextBlock Text="{Binding ElementName=AddressBox,
Path=(Validation.Errors),
Converter={StaticResource eToMConverter}}"
Foreground="White" FontFamily="Segoe UI"
Margin="8,2,8,3" TextWrapping="Wrap"
VerticalAlignment="Center"/>
</Border>
</StackPanel>
</ControlTemplate>
</Window.Resources>
<StackPanel Margin="5">
<TextBlock Margin="2">Enter An IPv4 Address:</TextBlock>
<TextBox x:Name="AddressBox"
Validation.ErrorTemplate="{StaticResource customvalidatortemplate}"
Margin="0,0,235.5,0">
<TextBox.Text>
<Binding ElementName="This" Path="IPAddress"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:IPv4ValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</Window>
ErrorsToMessageConverter.cs file :
public class ErrorsToMessageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var sb = new StringBuilder();
var errors = value as ReadOnlyCollection<ValidationError>;
if (errors != null)
{
foreach (var e in errors.Where(e => e.ErrorContent != null))
{
sb.AppendLine(e.ErrorContent.ToString());
}
}
return sb.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
IPv4ValidationRule.cs file :
public class IPv4ValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var str = value as string;
if (String.IsNullOrEmpty(str))
{
return new ValidationResult(false,
"Please enter an IP Address.");
}
var parts = str.Split('.');
if (parts.Length != 4)
{
return new ValidationResult(false,
"IP Address should be four octets, seperated by decimals.");
}
foreach (var p in parts)
{
int intPart;
if (!int.TryParse(p, NumberStyles.Integer, cultureInfo.NumberFormat, out intPart))
{
return new ValidationResult(false,
"Each octet of an IP Address should be a number.");
}
if (intPart < 0 || intPart > 255)
{
return new ValidationResult(false,
"Each octet of an IP Address should be between 0 and 255.");
}
}
return new ValidationResult(true, null);
}
}
I've found the solution (after a sleep:). In fact the exact element source you have to bind to can be accessed via the AdornedElementPlaceholder. It has a property called AdornedElement, TemplateBinding does not work in this case because TemplatedParent does not point to the TextBox, it's just another Control which is used for ErrorTemplate control. So the code should be like this:
<TextBlock Text="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors),
Converter={StaticResource eToMConverter}}"
Foreground="White" FontFamily="Segoe UI" Margin="8,2,8,3"
TextWrapping="Wrap" VerticalAlignment="Center"/>
Note about how we set the attached property Validation.Errors for the AdornedElement. Also note about the name adorner which is exactly the name you set for the AdornedElementPlaceholder. I've made a demo and surely it should work.
I am using IValueconverter interface to change the tooltip text of an image.
The tool tip should change based on label.
<Label Content="9898980001" Height="28" HorizontalAlignment="Left" Margin="1733,231,0,0" Name="lbl02scanning" VerticalAlignment="Top" Foreground="Blue" >
<Image Height="49" HorizontalAlignment="Right" Margin="0,131,113,0"
Name="img02scanning"
Source="/TEST;component/Images/LoadingStation.png" Stretch="Fill"
VerticalAlignment="Top" Width="30" Cursor="Hand">
<Image.ToolTip>
<StackPanel Background="AliceBlue">
<TextBlock Padding="5" Foreground="White" MinHeight="20"
Background="Blue" FontWeight="Bold"
Text="Scanning Station" />
<StackPanel Orientation="Horizontal">
<Image
Source="pack://application:,,,/TEST;component/Images/coilonsaddle_large.png"
Height="100" Width="100" />
<TextBlock Padding="10" TextWrapping="WrapWithOverflow"
MaxWidth="200" Background="AliceBlue"
Foreground="Black" FontWeight="Bold"
Text="{Binding ElementName=lbl02scanning, Path=Name,
ConverterParameter=255,
Converter={StaticResource FormatterFOrCoilToolTip}}"/>
</StackPanel>
<TextBlock Padding="5" Foreground="White" MinHeight="20"
Background="Blue" FontWeight="Bold"
Text="Report to admin in case of coil location mismatch"/>
</StackPanel>
</Image.ToolTip>
</Image>
The converter class:
public class FormatterForCoilToolTip : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(parameter.ToString() == "02")
{
return value.ToString() + " Startin";
}
else
{
return value.ToString() + " Finishing";
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
The tooltip's Textblock content is not changing. But if i change to:
Text="{Binding ConverterParameter=255, Converter={StaticResource FormatterFOrCoilToolTip}}
then it is working. But i want to pass the lbl02scanning text value. Why it is not working??
First of all you should bind to Content property and not Name property in case you want Text of Label.
Most importantly Tooltip does not lies in same Visual Tree as that of label, hence binding with elementName won't work. However, you can use x:Reference to get the element even if it doesn't exist in same Visual Tree.
Text="{Binding Source={x:Reference lbl02scanning}, Path=Content,
ConverterParameter=255,
Converter={StaticResource FormatterFOrCoilToolTip}}"/>
Note - x:Reference is introduced in WPF 4.0. If you are using WPF 3.5 you can't use this.
Update for error - service provider is missing the name resolver service
Just found out bug is reported at Microsoft site that x:Reference fails in case Target is Label. However, i couldn't reproduce this issue at my end since i have WPF 4.5 installed at my end and i guess they have fixed the issue in future version.
In case you target WPF 4.0, i would advise you to use TextBlock in place of Label:
<TextBlock Text="9898980001" Height="28" HorizontalAlignment="Left"
Margin="1733,231,0,0" Name="lbl02scanning" VerticalAlignment="Top"
Foreground="Blue" />
and then bind with Text property instead of Content.
Text="{Binding Source={x:Reference lbl02scanning}, Path=Text,
ConverterParameter=255,
Converter={StaticResource FormatterFOrCoilToolTip}}"/>
Either, you can refer to workaround provide under workarounds section here.
You can override the ProvideValue method of the Reference class and skip the reference search login in design time:
[ContentProperty("Name")]
public class Reference : System.Windows.Markup.Reference
{
public Reference()
: base()
{ }
public Reference(string name)
: base(name)
{ }
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget valueTargetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (valueTargetProvider != null)
{
DependencyObject targetObject = valueTargetProvider.TargetObject as DependencyObject;
if (targetObject != null && DesignerProperties.GetIsInDesignMode(targetObject))
{
return null;
}
}
return base.ProvideValue(serviceProvider);
}
Update with another workaround
This will work for all versions WPF 3.5, WPf 4.0 and WPF 4.5.
First of all bind Image Tag with content of label.
Second host your stackPanel inside ToolTip control so that you can
take benefit of PlacementTarget property.
Third bind with PlacementTarget.Tag of Tooltip.
Relevant code will look like this:
<Image Tag="{Binding ElementName=lbl02scanning,Path=Content}">
<Image.ToolTip>
<ToolTip>
<TextBlock Text="{Binding RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ToolTip},
Path=PlacementTarget.Tag,
ConverterParameter=255,
Converter={StaticResource FormatterFOrCoilToolTip}}"/>
</ToolTip>
</Image.ToolTip>
</Image>
Also you need to update converter code to put null check over there since PlacementTarget will be null until you open tooltip.
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value != null)
{
if (parameter.ToString() == "02")
{
return value.ToString() + " Starting";
}
else
{
return value.ToString() + " Finishing";
}
}
return String.Empty;
}
Try This
Text="{Binding Path=Content,ElementName=lbl02scanning, ConverterParameter=255, Converter={StaticResource FormatterFOrCoilToolTip}}
I just finished with watching practical mvvm presentation video on youtube and if I understand correctly moving logic from codebehing to view model is good practice and we should strive to this pattern.
Having this in mind I have one simple question. Inside xaml I have four radio buttons
<StackPanel x:Name="panel">
<RadioButton GroupName="myGroup" Name="Option1" Content="option one" IsChecked="True" Width="40"/>
<RadioButton GroupName="myGroup" Name="Option2" Content="option two" IsChecked="False" Width="80"/>
<RadioButton GroupName="myGroup" Name="Option3" Content="option three" IsChecked="False" Width="60"/>
</StackPanel>
I want to use this code inside viewmodel below to fetch selected radio btn.
var checkedValue = panel.Children.OfType<RadioButton>()
.FirstOrDefault(r => r.IsChecked.HasValue && r.IsChecked.Value);
Question is: How can I access to this panel object from the viewmodel? It's not data to use binding.
Update:
as #Rohit Vatss said "View objects should not be accessed from ViewModel" I would change question to How to know which radio button is selected using viewmodel?
You can do it by creating one property in you ViewModel, lets say GroupIndex
private int _groupIndex = 1;
public int GroupIndex
{
get { return _groupIndex; }
set
{
if (_groupIndex == value) return;
_groupIndex = value;
OnPropertyChanged("GroupIndex");
}
}
then create simple converter which will convert current GroupIndex value to true or false and back:
public class IndexBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
return false;
else
return (int)value == System.Convert.ToInt32(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
return null;
else if ((bool)value)
return System.Convert.ToInt32(parameter);
else
return DependencyProperty.UnsetValue;
}
}
and then bind your RadioButton to GroupIndex which will will be set to 1, 2 or 3 depending on which RadioButton is checked
<StackPanel>
<StackPanel.Resources>
<local:IndexBooleanConverter x:Key="IndexBooleanConverter"/>
</StackPanel.Resources>
<RadioButton Content="Option1" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=1}"/>
<RadioButton Content="Option2" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=2}"/>
<RadioButton Content="Option3" IsChecked="{Binding Path=GroupIndex, Converter={StaticResource IndexBooleanConverter}, ConverterParameter=3}"/>
</StackPanel>
In this case GroupIndex is int but you can also use same logic if for example your GroupIndex is an enum
Well an aprroach would be for example using a Command and a Command Parameter on the radiobuttons Binded to your viewmodel. For example:
<RadioButton GroupName="myGroup" Name="Option1" Content="option one" IsChecked="True" Width="40" Command="{Binding RbCheckedCommand}" CommandParameter="RB1"/>
<RadioButton GroupName="myGroup" Name="Option2" Content="option two" IsChecked="False" Width="80" Command="{Binding RbCheckedCommand}" CommandParameter="RB2"/>
<RadioButton GroupName="myGroup" Name="Option3" Content="option three" IsChecked="False" Width="60" Command="{Binding RbCheckedCommand}" CommandParameter="RB3"/>
Then on your ViewModel:
private readonly DelegateCommand<object> rbCheckedCommand;
public ICommand RbCheckedCommand
{
get { return this.rbCheckedCommand; }
}
private void RbCheckedCommandExecute(object obj)
{
string rbselected = obj.ToString();
}
And on the constructor of the class:
this.rbCheckedCommand = new DelegateCommand<object>(RbCheckedCommandExecute);
You will have to use the prism adding:
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
And making your class inherits from NotificationObject so you can use the Property changed easily.
Hope it helps.