Hello Folks,
Often we have requirement in our project that requires us to create listbox of items.
Till this point it is fine, things grow complex when we require to create listbox
with checkbox. The main idea behind creating this is to ensure user don't have to
click multiples time while moving data from one list box to other.
On way to do this is to create a StackPanel with vertical orientation. Create checkbox
and keep on adding checkbox to it. The only downside of this approach is that each
time we need to access the data of the checkbox we have to do lot of traversing
up and down.
The other approach is what I am going to discuss.
In this sample I have a Vehicle class with two property ID and Name.
|
public
class Vehicle
{
public int ID {
get; set; }
public string Name {
get; set; }
}
List<Vehicle>
vehicleList = new List<Vehicle>()
{
new Vehicle(){ ID=1, Name="BMW"}, new
Vehicle(){ ID=2, Name="Honda"},
new Vehicle(){ ID=3, Name="Accord"}, new
Vehicle(){ ID=4, Name="Audi"},
new Vehicle(){ ID=5, Name="Toyota"}, new
Vehicle(){ ID=6, Name="Ford"},
new Vehicle(){ ID=7, Name="Maruti"}, new
Vehicle(){ ID=8, Name="Ducati"},
new Vehicle(){ ID=9, Name="Skoda"}, new
Vehicle(){ ID=10, Name="Mercedes"}
};
|
The required XAML file. i.e. two ListBox and two buttons to Add and Remove items
from list.
|
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"
/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="200"
/>
</Grid.ColumnDefinitions>
<ListBox x:Name="lstAvailable" Grid.Column="0" Height="250" />
<ListBox x:Name="lstSelected" Grid.Column="2" Height="250" />
<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Center">
<Button x:Name="btnAdd" Content="Add >>" Click="btnAdd_Click" Width="90"
Margin="0,0,0,10"/>
<Button x:Name="btnRemove" Content="<<
Remove" Click="btnRemove_Click" Width="90"/>
</StackPanel>
</Grid>
|
Next create a method that will perform the task of creating the Listbox with checkbox.
Here I have create a collection of ListboxItem and assigned it to the Listbox.
|
private void CreateListBoxWithCheckBox(ListBox listBox, List<Vehicle> list)
{
List<ListBoxItem> listBoxItem
= new List<ListBoxItem>();
foreach (var item
in list)
{
ListBoxItem tempItem = new
ListBoxItem();
CheckBox chk = new
CheckBox();
chk.Content = item.Name;
chk.Tag = item;
tempItem.Content = chk;
listBoxItem.Add(tempItem);
}
listBox.ItemsSource = listBoxItem;
}
|
Next handled the button add and Remove click event. Let's look into the code of
Add button click, similar is the code for remove and can be easily replicated.
|
private void btnAdd_Click(object sender, RoutedEventArgs
e)
{
List<ListBoxItem> listItems
= this.lstAvailable.ItemsSource
as List<ListBoxItem>;
if (null != listItems)
{
foreach (var
item in listItems)
{
CheckBox chk = item.Content as CheckBox;
if (null
!= chk && chk.IsChecked.Value)
{
Vehicle selectedVehicle
= chk.Tag as Vehicle;
if (null
!= selectedVehicle)
{
var result
= this.selectedList.Where(sl => sl.ID ==
selectedVehicle.ID).FirstOrDefault();
if (null
== result)
{
this.selectedList.Add(selectedVehicle);
this.availableList.Remove(selectedVehicle);
}
else
{
//
TODO: Added code to flag message to user that this item already exist.
}
}
}
}
this.CreateListBoxWithCheckBox(this.lstAvailable, this.availableList);
this.CreateListBoxWithCheckBox(this.lstSelected, this.selectedList);
}
}
|
If you look into the code you can see that I am maintaining separate list for items
present in available and selected listbox. The idea behind this is to ensure cleaner
separation of UI and code handling. Using this style I can easily perform the save
and update operation without having to look into the listbox again.
Download complete solution