Click here to Skip to main content
12,761,216 members (30,740 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

45K views
1.9K downloads
40 bookmarked
Posted 14 Oct 2008

WPF CheckListBox/RadioListBox + CheckComboBox/RadioComboBox

, 31 Oct 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
Intended for LOB applications: WPF CheckListBox/RadioListBox with bound datatype.

Introduction

In LOB applications, we have to design many windows, and many entities are bound to entry fields. Also, sometimes, there are enums or bool[] arrays to be used. Therefore, I had a look at the chances I got to bind some user control to an enum data type. There is no CheckListBox as in WinForms, and WPF shows the whole power when a ListBox has to be customized to a CheckListBox. A template-style will do for that more or less. It is more difficult when the CheckListBox should be bound to a flagged enum or is a RadioListBox.

WPFCheckListBox_Sample.png

What I wanted to achieve

In the case of showing all enum items to the user, I wanted to do the following:

  • drop a control from the toolbox on the form
  • set a binding to the entity, specifying the property name

With declaring the property in the business object as an enum type, I already do everything beforehand, so I do not have to think again about the enum items and setting the ItemSource, and so on.

Using the code

Like the specs, you just drop the desired control onto the form and set the binding. In the sample, all the necessary parts are contained to show the functionality:

<clb:RadioListBox Name="listBoxType" 
                  CheckedValue="{Binding PropType, Mode=TwoWay}"/>

<clb:CheckListBox Name="listBoxFeature"
                  CheckedValue="{Binding PropFeature, Mode=TwoWay}"/>

The CheckedValue dependency property holds the bound data property from the entity. It is important to specify that the binding is TwoWay.

Sometimes, you don't have an enum data type but a bool[] array or anything else. In this case, there is no way to find out what the items to appear in the selection list are. So, you must somehow declare and propagate the collection to the control. You can do this in the code or in XAML. In any case, this has to be done before the first binding occurs. Here is a sample in XAML:

<Window.Resources>
    <coll:ArrayList x:Key="actionList">
        <clb:CheckItem KeyValue="0" Display="action 0"/>
        <clb:CheckItem KeyValue="1" Display="action 1"/>
        <clb:CheckItem KeyValue="2" Display="action 2"/>
    </coll:ArrayList>

    <coll:ArrayList x:Key="arrayList">
        <clb:CheckItem KeyValue="0" Display="item 0"/>
        <clb:CheckItem KeyValue="1" Display="item 1"/>
        <clb:CheckItem KeyValue="2" Display="item 2"/>
        <clb:CheckItem KeyValue="3" Display="item 3"/>
    </coll:ArrayList>
</Window.Resources>

<clb:RadioListBox Name="listBoxAction" 
                  CheckListArray="{StaticResource actionList}" 
                  CheckedValue="{Binding PropAction, Mode=TwoWay}" />

<clb:CheckListBox Name="listBoxArray"
                  CheckListArray="{StaticResource arrayList}" 
                  CheckedValue="{Binding PropArray, Mode=TwoWay}"/>

The CheckListArray holds the collection to be shown in the list. Specify the KeyValue if you want the chosen value as, e.g., an integer.

What is happening when running

In the underlying base class of the CheckListBox and RadioListBox, the DataContextChanged is used to intercept on a binding to the bound property. In this case, the CheckedValue.OnDataContextChanged, the type of the bound property, is evaluated, and either a prepared collection, or the items of the enum are bound to the ItemSource of the ListBox. To keep track of the changes, a ViewModel (I call it this way, might not meet the name) is created to control the ListBox and the bound property.

This class is important, the enum could be of various types: byte, int, uint, long, ulong... They all work neat because the ViewModel uses a UInt64 array of values to keep track of the enumeration values. The corresponding data types are boxed/unboxed accordingly.

The [Flags] attribute is very important on an enum data type. Without this, only one choice can be checked, and even a CheckListBox is used.

If someone wants to do all this before the first binding, the method CreateViewModel could be called manually by specifying the corresponding type.

public void CreateViewModel(Type boundType)
{
   if (boundType==null)
   {
      return;
   }
   if (this.CheckViewModel == null || this.CheckViewModel.BoundType != boundType)
   {
      Type _viewBase = typeof(CheckViewModel<>);
      Type _viewType = _viewBase.MakeGenericType(boundType);

      this.CheckViewModel = (ICheckViewModel)Activator.CreateInstance(_viewType);
      this.CheckViewModel.HostParent = this;
      this.CheckViewModel.IsRadioMode = this.isRadioMode;  // is passed by constructor

      if (this.CheckListArray != null)
      {
          List<CheckItem> _itemList = new List<CheckItem>();
          foreach (CheckItem _checkItem in this.CheckListArray)
          {
             _itemList.Add(_checkItem);
          }
          this.CheckViewModel.CheckItems = _itemList;
      }
      else
      {
          this.CheckViewModel.InitDiscovery();
      }
   }
   if (this.CheckViewModel != null && this.ItemsSource == null)
   {
      this.ItemsSource = this.CheckViewModel.CheckItems;
      this.DisplayMemberPath = "Display";
      this.SelectedValuePath = "KeyValue";
      this.SelectionMode = SelectionMode.Single;
   }
}

Overview

The CheckModelView is encapsulated in the CheckListBoxBase. From this base class, the CheckListBox and the RadioListBox are derived. The main reason for this is the different template they use for the ListBox:

CheckViewModel.png

So maybe, it helps someone, or some real WPF-experts (you name them) might come up with a better solution. Cheers!

History

  • 15.10.2008 > Initial publication.
  • 31.10.2008 > Update: CheckComboBox and RadioComboBox.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

christoph brändle
Software Developer
Switzerland Switzerland
No Biography provided

You may also be interested in...

Comments and Discussions

 
Questiondatasource Pin
Fernando E. Braz3-Jun-13 9:59
memberFernando E. Braz3-Jun-13 9:59 
QuestionHow to customize clb:CheckItem? Pin
Masupilamix3-Dec-11 6:02
memberMasupilamix3-Dec-11 6:02 
AnswerRe: How to customize clb:CheckItem? Pin
christoph braendle6-Dec-11 3:55
memberchristoph braendle6-Dec-11 3:55 
QuestionHow to bind date to CheckListArray?Not using StaticResource. Pin
artan00810-May-10 18:35
memberartan00810-May-10 18:35 
AnswerRe: How to bind date to CheckListArray?Not using StaticResource. Pin
Member 32246501-Jun-10 1:14
memberMember 32246501-Jun-10 1:14 
GeneralGet the following error Pin
eve1236-Feb-10 21:45
membereve1236-Feb-10 21:45 
GeneralRe: Get the following error Pin
christoph braendle9-Feb-10 0:23
memberchristoph braendle9-Feb-10 0:23 
GeneralLike it Pin
Sacha Barber25-Oct-08 22:56
mvpSacha Barber25-Oct-08 22:56 
GeneralRe: Like it Pin
christoph braendle31-Oct-08 12:28
memberchristoph braendle31-Oct-08 12:28 
GeneralRe: Like it Pin
Sacha Barber31-Oct-08 23:18
mvpSacha Barber31-Oct-08 23:18 
GeneralRe: Like it Pin
christoph braendle1-Nov-08 4:53
memberchristoph braendle1-Nov-08 4:53 
GeneralRe: Like it Pin
Sacha Barber1-Nov-08 5:13
mvpSacha Barber1-Nov-08 5:13 
GeneralTimely Work Pin
Kavan Shaban25-Oct-08 2:12
memberKavan Shaban25-Oct-08 2:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170217.1 | Last Updated 31 Oct 2008
Article Copyright 2008 by christoph brändle
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid