I am relatively new to WPF and would like to create a UserControl that contains three RadioBoxes in a StackPanel. Each of the radio buttons has an IsChecked property. I want to ease access to that selection by publishing an integer property that indicates the current selection, call it SelectedIndex.
So when the first radio is checked, the SelectedIndex value of my user control shall be 0; when the second radio is checked, SelectedIndex shall be 1, and so on. This should probably work in either direction: when the user clicks on the radio box, the SelectedIndex value shall change accordingly. And when the SelectedIndex value is changed by code or maybe even some data binding, the UI controls shall update accordingly.
How can I do that with XAML code? I have the following code now:
public partial class CommandControl : UserControl
{
public static readonly DependencyProperty SelectedIndexProperty =
DependencyProperty.Register("SelectedIndex", typeof(int), typeof(CommandControl));
public int SelectedIndex
{
get
{
return (int) GetValue(SelectedIndexProperty);
}
set
{
SetValue(SelectedIndexProperty, value);
}
}
public CommandControl()
{
InitializeComponent();
}
}
And the XAML part:
<UserControl x:Class="MyNamespace.CommandControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="65" d:DesignWidth="219"
x:Name="me">
<StackPanel HorizontalAlignment="Left" Name="stackPanel1" VerticalAlignment="Center" Orientation="Horizontal">
<RadioButton Content="Disable" Name="disableRadio" VerticalAlignment="Center" IsChecked="True" />
<RadioButton Content="Enable" Name="enableRadio" VerticalAlignment="Center" Margin="5,0,0,0" />
<RadioButton Content="Configure" Name="configureRadio" VerticalAlignment="Center" Margin="5,0,0,0" />
</StackPanel>
</UserControl>
I know how to pass values (like one of the RadioButton’s Text for example) from a property of my UserControl. But this time, I need to map an “external” int value to three “internal” bool values, each true when the number has a specific value. I guess that should be done directly in XAML, but I cannot figure out how to accomplish that.
Or would it be a better idea to write C# code for that conversion? I could possibly do that now, but I’m still unsure about the special DependencyProperty code which, I imagine, may change its value without passing my setter.
The most common solution is not to attempt to use a numerical representation of which
RadioButtonis selected because you’re going against the flow if you try.However, to try and answer the question nonetheless…
I don’t think I’d try to solve this in XAML, because this isn’t playing to XAML’s strengths. Something people relatively new to WPF often do is to try and do everything possible in XAML whether it makes sense or not because they’ve got the idea from somewhere that it’s what you’re supposed to do.
I’m not saying it’s impossible. Lest you think I’m trying to talk you out of it because I don’t know how to do it in XAML, I’ll show exactly how I think you shouldn’t do it. This works, for small values of “works”:
but this is pretty icky. First of all, Visual Studio will pretend there’s an error – for as long as you have this Xaml file open it will report the error “‘CommandControl’ TargetType does not match type of element ‘UserControl’.” Secondly, this only works if you put the
Styleafter the main body of the user control. Frankly these sorts of issues are code smells – a clue that you may be doing things wrong. And in this case, you would be.By the way, Visaul Studio’s not telling the truth with the error message – that’s not a compile-time error, and the program will build and run, and using the following main window content:
I’ve verified that this does correctly update the property.
But this is all wrong.
For one thing, what you’re trying to create here is programatic functionality – you’re determining how the control’s API behaves. This is well outside XAML’s strengths. Heck, even embedding interactive behaviour in XAML is questionable. My view is that XAML is mainly for the layout and appearance of your app.
So the codebehind is really the place for what you’re doing. Just use good old-fashioned event handling. Be sure to use
SetCurrentValueto update your depenedency property’s value. Don’t just use the setter, because that will mess up any data bindings or other DP-specific uses of your property, and will essentially defeat the point of making it a DP in the first place.Also, I wouldn’t call it
SelectedIndexbecause that’s a property name that usually means something specific in WPF – it’s mainly used by ItemsControl-derived controls that support selection. That’s not what you’re doing here, so I’d be inclined to pick a name that doesn’t already commonly have a meaning. Except as I already said, I don’t think I’d be using a numeric index in any case.