WPF Data Bound RadioButtonList

|

During the process of writing a WPF application recently, I had the need for a data bound list of items where the options had to be mutually exclusive, so I figured something like a list of RadioButtons would be in order.

However, when I started looking around I could not find a RadioButtonList or anything that fitted the bill out-of-the-box. Therefore, I thought I’d put something together myself; I also needed to have the list render horizontally rather than vertically. This is what I came up with:

<!-- Item Style for the ListBoxItem to add a RadioButton -->
<Style x:Key="RadioButtonItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Margin" Value="0,0,5,0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border BorderThickness="0" Background="Transparent">
                    <!-- Note: IsChecked is bound to IsSelected-->
                    <RadioButton
                        Focusable="False"
                        IsHitTestVisible="False"
                        IsChecked="{TemplateBinding IsSelected}">
                        <ContentPresenter />
                    </RadioButton>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- Turns the ListBox in to a Horizontal ListBox -->
<ItemsPanelTemplate x:Key="HorizontalItemsPanel">
    <VirtualizingStackPanel
        Orientation="Horizontal" />
</ItemsPanelTemplate>

I defined a Style and the ItemsPanelTemplate in the Resources property of my Window that contains all the necessary XAML for the effects I need; note that you could just as easily define this XAML inline on the ListBox as opposed to using the Resources property. I then applied these two new elements to an instance of ListBox using the following mark-up:

<ListBox
    BorderThickness="0"
    ItemsSource="{Binding MyDataList}"
    SelectedValue="{Binding MyDataListSelectedValue}"
    ItemContainerStyle="{StaticResource RadioButtonItemStyle}"
    ItemsPanel="{StaticResource HorizontalItemsPanel}" />
  

I’ve highlighted where I’ve used the two resources.

For this example the data list is trivial and is provided by a ViewModel class attached to the DataContext of the Window; I’m only showing the code here as a example of how you can add sample data to an application, as well as proving that the above XAML all works as expected using a bound list of data:

public class MainWindowViewModel
{
    public IEnumerable<string> MyDataList
    {
        get
        {
            yield return "Stan";
            yield return "Cartman";
            yield return "Kenny";
            yield return "Karl";
        }
    }

    public string MyDataListSelectedValue
    {
        get { return "Cartman"; }
        set { /* TODO: save the value */ }
    }
}

<!-- XAML -->
<Window.DataContext>
    <vm:MainWindowViewModel />
</Window.DataContext>

Here’s what it all looks like in the Visual Studio designer:

image

And there we have it, job done. Hope this helps someone, happy XAML hacking.

WPF: MV-VM Sample Application with Navigation

|

I have recently been reminded of how difficult it can be to get started when you are trying to build an application and have been given a completely clean sheet of paper to start from – in terms of the application architecture and design – the options are limitless, which can at times be a little daunting.

Recently, to help a colleague combat the clean sheet of paper syndrome, we had a conversation about some of the patterns and ideas that he might want to consider with the particular application he is writing with WPF. The result of the meeting, after 90 minutes of discussion, was a whiteboard full of pattern names, blocks and arrows, which all appeared to be clearly understood by all involved at the time and we left feeling that it was a job well done. However, it occurred to me on the drive home that when faced with a blank code editor the next morning, would all those squiggles and arrows still make sense?

That lead me to thinking that a simple application that outlines not just the theory of some of the standard patterns that I use for building applications today, but also shows concrete implementations, real strategies, real code and compromises, not just code snippets of isolated issues, but a complete, albeit simple, application.

The following sample application, and accompanying screencast, are the results of that thinking. When I handed off both of these to my colleague it also occurred to me that others might benefit from the sample and would also serve as a reminder for me in the future, hence this post.

The application itself is somewhat trivial, but the patterns and architecture discussed are not. The sample covers:

  • ModelView-ViewModel (Application architecture)
  • Repository and Service Patterns (data modelling and retrieval)
  • Command Pattern (for communication between the Views and the ViewModels) [1]
  • Various different types of View, including Page and Window [2]
  • Text to FlowDocument value converter
  • Poor man’s Dependency Injection

Click here to download the sample code.

I sincerely hope that you get some value out of this post, and as usual if you have any comments, questions, flames, enhancements I would love to hear from you. In the meantime, think deeply and enjoy.


[1] Including a hybrid DelegateCommand class inspired by standard MV-VM commanding, sometimes referred to as a RelayCommand, and Prism’s DelegateCommand implementation

[2] Page based Views and navigation are specific to the application discussed in the 90 minute meeting, where what you would usually see in a traditional MV-VM discussion would be UserControl instances as the Views. I think the use of Pages in the sample makes it a more interesting sample that shows more varied View types than you would normally see.