<ListBox Margin="10" HorizontalAlignment="Stretch" Name="lbSheets"
VerticalAlignment="Stretch" Width="Auto" Grid.Row="1" MinWidth="321"
MinHeight="40" HorizontalContentAlignment="Left"
ItemTemplate="{StaticResource ListBoxItemTemplate}" VerticalContentAlignment="Top" Background="#FFDCEBEE" SelectionMode="Single" SelectionChanged="lbSheets_SelectionChanged">
</ListBox>
<DataTemplate x:Key="ListBoxItemTemplate" >
<WrapPanel>
<CheckBox Focusable="False" IsChecked="{Binding Selected}" VerticalAlignment="Center" />
<ContentPresenter Content="{Binding FullName, Mode=OneTime}" Margin="2,0" />
</WrapPanel>
</DataTemplate>
In my example, I am then binding a domain model object that implements INotifyPropertyChanged, and I have a boolean property for Selected, when the checkbox is checked, it will toggle this value, and vice versa. The text that is displayed is from a property called ‘FullName’, as specified in the DataTemplate.
However, I wanted to be able to check the checkboxes by clicking on the text next to them, not by pinpointing the check box. I tried a number of ways of doing this before finally arriving at a solution.
I ended up suing the ‘MouseUp’ event on the ContentPresenter from my DataTemplate
<DataTemplate x:Key="ListBoxItemTemplate" >
<WrapPanel>
<CheckBox Focusable="False" IsChecked="{Binding Selected}" VerticalAlignment="Center" />
<ContentPresenter Content="{Binding FullName, Mode=OneTime}" Margin="2,0" MouseUp="ContentPresenter_MouseUp" />
</WrapPanel>
</DataTemplate>
private void ContentPresenter_MouseUp(object sender, MouseButtonEventArgs e)
{
string text = ((TextBlock) e.OriginalSource).Text;
foreach (var item in this.lbSheets.Items)
{
PrintableSheet sheetItem = (PrintableSheet) item;
if (sheetItem.FullName.Equals(text))
{
sheetItem.Selected = !sheetItem.Selected;
}
}
}
5 comments:
Very timely - I have been using a rather hacked-together combination of ListView & GridView to achieve a similar affect. This is nice and simple.
One question - I have tried this solution here, but I can't get the MouseUp event to check the box. In debugging, all the (boolean) variables get toggled correctly, but the checkbox does not visually update in the window.
Any ideas?
FWIW: My application for this "CheckListBox" is to add and remove filters to a datagrid.
Excellent article Rod...Can u please provide full code for this example also with this article...I have to achieve similar functionality of clicking on textbox content & toggling the checkbox's check state but with some differences...Kindly revert back ASAP.
You can also get the checkbox directly by casting the sender as ContentPresenter, casting it's parent as WrapPanel, casting it's first child as CheckBox and then setting IsChecked on the checkbox. Should be faster than searching through all your internal data and allows for some items to have identical names. A little more dependent on the UI but you're already making assumptions there.
Why not use content of the checkbox for the text instead. The a single click on the text will result in checking/unchecking the checkbox.
Like:
Why not use content of the checkbox for the text instead? The a single click on the text will result in checking/unchecking the checkbox.
Like:
Post a Comment