ListBox内Checkbox无法触发Checked/Unchecked事件问题求助
问题描述
刚接触MVVM模式,遇到一个问题:把Checkbox作为ListBox的项时,它的Checked和Unchecked事件触发不了;但把Checkbox放在ListBox外(比如StackPanel里)时,事件能正常触发。
用到的代码
<Border Grid.Row="1" Grid.Column="0" BorderThickness="2" Grid.RowSpan="3" BorderBrush="{StaticResource MainMenuColor}"> <ListBox ItemsSource="{Binding ListBoxItems}" Background="Transparent" Foreground="{StaticResource MainMenuColor}"> <ListBox.ItemTemplate> <DataTemplate> <CheckBox FontFamily="{StaticResource FontProtokoll}" IsChecked="{Binding IsChecked}" Content="{Binding Path=Text}" Foreground="{StaticResource MainMenuColor}"> <behav:Interaction.Triggers> <behav:EventTrigger EventName="Checked"> <behav:InvokeCommandAction Command="{Binding CheckedOrUncheckedCommand}"/> </behav:EventTrigger> </behav:Interaction.Triggers> </CheckBox> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Border>
问题原因与解决办法
根本原因:DataTemplate里的Checkbox默认会把绑定上下文指向ListBoxItems集合里的单个子项对象,而不是ListBox所在的父ViewModel。如果你的子项对象里没定义
CheckedOrUncheckedCommand这个命令,自然触发不了。而放在ListBox外时,绑定上下文是父ViewModel,命令存在所以能正常工作。解决办法:
- 绑定到父ViewModel的命令:用
RelativeSource指定绑定源为父级的ListBox,进而找到父ViewModel的命令,修改代码如下:<behav:InvokeCommandAction Command="{Binding DataContext.CheckedOrUncheckedCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"/> - 把命令放到子项模型里:如果每个子项的选中逻辑需要独立处理,就在ListBoxItems的子项类里定义
CheckedOrUncheckedCommand,并实现对应的逻辑。 - 利用IsChecked绑定直接处理:既然已经绑定了
IsChecked="{Binding IsChecked}",可以直接在子项模型的IsChecked属性的setter方法里处理选中/取消选中的逻辑,这更贴合MVVM的设计思路,也不用额外加事件触发器。
- 绑定到父ViewModel的命令:用
内容的提问来源于stack exchange,提问作者stutski
相关产品推荐
相关产品推荐

