WPFAQS – C# enum Data-bindings

WPFAQS – as the name suggests, is about frequently asked questions (faqs) on WPF.  It is a new series and I’ll be posting answers to interesting questions regularly in this series.

WPFAQS(001) – How to Databind C# Enums in WPF with a Style
Prerequisite/s – WPF-Style and Templates.

Here is an example of final output image, that I am looking for –

EnumImage003 

Its about an enum of System.Threading.ThreadState type and If you look closely into the image, the thread running state is “bold” and also the item in the combo-box is a radio-button. We’ll see how we deal with this later. Here is what I pulled out from the framework, and given my own name, i.e. DotNetThreadStates.

    public enum DotNetThreadStates
    {
        Running = 0,
        SuspendRequested = 2,
        Background = 4,
        Unstarted = 8,
        WaitSleepJoin = 32,
        Suspended = 64,
        AbortRequested = 128,
        Aborted = 256
    }

The simplest way to databind this enum is by using code behind :–

            comboBoxThreadStates.ItemsSource = Enum.GetValues(typeof(DotNetThreadStates));

WPF is cool that we can do all this stuff in XAML using ObjectDataProvider :–

        <ObjectDataProvider x:Key="DotNetThreadStatesEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="win:DotNetThreadStates" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

You need to include this assembly in the XAML, like –

xmlns:sys="clr-namespace:System;assembly=mscorlib" 

Here is the XAML code that will do the rest of the job..

        <ComboBox x:Name="comboBoxThreadStates"
                ItemsSource="{Binding Source={StaticResource DotNetThreadStatesEnum}}"
                Height="23" 
                Margin="12,22,12,0"  
                VerticalAlignment="Top" />

Here is the output for it –

EnumImage001

The Databinding part of enum is a snap in WPF i.e. create an instance of “ObjectDataProvider” and bind it to the “ItemsSource” property of “ComboBox” and viola, we are done. Do you really think we are done, I don’t think so. We need the “thread running state” be “bold”. How we gonna do that, well “DataTemplate” is a rescue to it. It renders data to the user-interface as you want. So where ever that bound-data will appear in the application will be replaced by the Template defined in “DataTemplate”. Here you go :–

        <DataTemplate DataType="{x:Type win:DotNetThreadStates}">
            <TextBlock Text="{Binding}" x:Name="PART_Text" />
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding}" Value="Running">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread Running" />
                    <Setter TargetName="PART_Text" Property="FontWeight" Value="Bold" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="Background">
                    <Setter TargetName="PART_Text" Property="Text" Value="Background Thread" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="Unstarted">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread Not Started" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="SuspendRequested">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread Requested To Suspend" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="Suspended">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread Suspended" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="WaitSleepJoin">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread in Wait-Sleep-Join State" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="AbortRequested">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread in Abort-Requested State" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="Aborted">
                    <Setter TargetName="PART_Text" Property="Text" Value="Thread Aborted" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>

In this case, the data that is an enum value will eventually be replaced by “TextBlock” whose "Text" property is databounded to the equivalent “enum” value. The question is how the value will be selected. In the code behind we can achieve this by using "switch" statement. In "XAML", you can achieve this with the aid if “DataTriggers”. So when the data-bounding mechanism encounters the “value” == "Running" a trigger/event will be fired and that value will be replaced with the corresponding value in the setter. Here is how the output will look like now.

EnumImage002

We are almost there.. One final requirement “combo-box item should be a radio-button.” and that can easily be achieved with a WPF-Style.. here you go.

        <Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}" >
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Border Background="Transparent">
                            <RadioButton Content="{TemplateBinding ContentControl.Content}"  
                                IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType={x:Type ComboBoxItem}},Path=IsSelected}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Its time for an assignment : Requirement changed (It happen in the real world very often :) I need  CheckBoxes instead of RadioButons in the Style, Here is what it should look like with option of multiple selection and those selections should appear as the “combobox” selected item, separated with “>>” like a breadcrumb.

EnumImage004

Please, keep in mind that we shall be able to select multiple items, Its a little bit tricky one, so be careful, .Post your answers, I will post mine pretty soon :)

I will discuss in detail about WPF-Styles and Templates in some other post. That's all for now and look forward to your feed-back. enjoy :)
PS – The project/source code is attached, feel free to download it.

 

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!
Comments are closed