Introduction
The article 'http://www.c-sharpcorner.com/Blogs/12324/creating-checklistbox-using-xaml-in-wpf.aspx' I have explained how to create WPF Check List Box using XMAL code.
Now I am going to explain how to create same thing using C# code. To listing check boxes you need to one List box, one Wrap Panel and one check box. The list box will list the check boxes, the wrap panel will be added to template panel of list box and the CheckBox will be added to the item template of list box. Follow the bellow steps to create Check List Box
Steps
- Open Visual Studio Click on the new project option in the start page. The Project Template Window will open; select Class Library Project Template from the Project Template Window.
- Rename the Project to Custom Control, and then click OK Button. Open the Solution Explorer and rename the class from Class1 to Check List Box.
- Inherit your Check List Box Class
from base control List Box, avoid to access the two properties of
Base Class List Box Control named DisplayMemberPath and SelectedValuePath
by reinitializing these properties. see the code bellow:
new private string DisplayMemberPath { get; set; }
new private string SelectedValuePath { get; set; }
- Declare on string property(ContentPath)
to set the content of Check Box that will listed in Check List Box.
See the bellow code
public string ContentPath { get; set; }
- Again declare one more string property to
set the IsChecked property of check box
public string IsSelectPath { get; set; }
- Override the Initialized function, in that function adds the Wrap Panel in to the ItemsPanelTemplate of ListBox.
- To add the wrap panel in to the item panel template, create the object of FrameworkElementFactory class and pass Wrap panel as type to the parameter of that class. Set the OrientationProperty of wrap panel to Horizenal ,MaximumWidth and MaximumHeight property to width and height of ListBox and Itemhostproperty of wrap panel set to true.
- Declare the object of
ItemPanelTemplate class and set the VisualTree property to
FrameworkElementFactory, again set it to the ItemsPanelTemplate
of list box. See the bellow code.
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
FrameworkElementFactory Factory = new FrameworkElementFactory(typeof(WrapPanel));
Factory.SetValue(WrapPanel.OrientationProperty, Orientation.Horizontal);
Factory.SetValue(CheckBox.MaxWidthProperty, this.Width);
Factory.SetValue(CheckBox.MinHeightProperty, this.Height);
Factory.SetValue(WrapPanel.IsItemsHostProperty, true);
ItemsPanelTemplate IPT = new ItemsPanelTemplate();
IPT.VisualTree = Factory;
this.ItemsPanel = IPT;
}
- Again override the OnItemSourceChenged
,do the same step like 6, 7 and 8. Create the object of
FrameworkElementFactory class and pass the CheckBox class as type
to the parameter of FrameworkElementFactory's Contracture. Set the CheckBox
properties like name, width and add Click event. See the bellow code:
FrameworkElementFactory FEF = new FrameworkElementFactory(typeof(CheckBox));
FEF.SetValue(CheckBox.NameProperty, "txtChecked");
FEF.SetValue(CheckBox.WidthProperty, 50.00);
FEF.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(CheckBox_CheckChanged), true);
if (!string.IsNullOrEmpty(this.ContentPath))
{
Binding CBG = new Binding(this.ContentPath);
FEF.SetBinding(CheckBox.ContentProperty, CBG);
}
if (!string.IsNullOrEmpty(this.IsSelectPath))
{
Binding SBG = new Binding();
SBG.Path = new PropertyPath(this.IsSelectPath);
SBG.Mode = BindingMode.TwoWay;
SBG.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
FEF.SetBinding(CheckBox.IsCheckedProperty, SBG);
}
DataTemplate IT = new DataTemplate();
IT.VisualTree = FEF;
this.ItemTemplate = IT;
- In the click event of CheckBox set
the List Box items that contains the CheckBox selected. See the
bellow code how to do that.
CheckBox CB = (CheckBox)sender;
ContentPresenter CP = (ContentPresenter)CB.TemplatedParent;
ListBoxItem LBI =(ListBoxItem) CP.TemplatedParent;
LBI.IsSelected =(bool) CB.IsChecked;
e.Handled = true;
- If you covered all the 10 steps your
CheckBoxList is done,.
Code of the Class
public class CheckListBox : ListBox
{
//Properties of Parent
new private string DisplayMemberPath { get; set; }
new private string SelectedValuePath { get; set; }
public string ContentPath { get; set; }
public string IsSelectPath { get; set; }
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
FrameworkElementFactory Factory = new FrameworkElementFactory(typeof(WrapPanel));
Factory.SetValue(WrapPanel.OrientationProperty, Orientation.Horizontal);
Factory.SetValue(CheckBox.MaxWidthProperty, this.Width);
Factory.SetValue(CheckBox.MinHeightProperty, this.Height);
Factory.SetValue(WrapPanel.IsItemsHostProperty, true);
ItemsPanelTemplate IPT = new ItemsPanelTemplate();
IPT.VisualTree = Factory;
this.ItemsPanel = IPT;
}
protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
{
base.OnItemsSourceChanged(oldValue, newValue);
FrameworkElementFactory FEF = new FrameworkElementFactory(typeof(CheckBox));
FEF.SetValue(CheckBox.NameProperty, "txtChecked");
FEF.SetValue(CheckBox.WidthProperty, 50.00);
FEF.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(CheckBox_CheckChanged), true);
if (!string.IsNullOrEmpty(this.ContentPath))
{
Binding CBG = new Binding(this.ContentPath);
FEF.SetBinding(CheckBox.ContentProperty, CBG);
}
if (!string.IsNullOrEmpty(this.IsSelectPath))
{
Binding SBG = new Binding();
SBG.Path = new PropertyPath(this.IsSelectPath);
SBG.Mode = BindingMode.TwoWay;
SBG.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
FEF.SetBinding(CheckBox.IsCheckedProperty, SBG);
}
DataTemplate IT = new DataTemplate();
IT.VisualTree = FEF;
this.ItemTemplate = IT;
}
private void CheckBox_CheckChanged(object sender, RoutedEventArgs e)
{
CheckBox CB = (CheckBox)sender;
ContentPresenter CP = (ContentPresenter)CB.TemplatedParent;
ListBoxItem LBI = (ListBoxItem)CP.TemplatedParent;
LBI.IsSelected = (bool)CB.IsChecked;
e.Handled = true;
}
}
Join the conversation! Your thoughts help the community grow.