我有一个ListBox
定义如下:
<ListBox
DisplayMember="Name"
ItemsSource="{Binding Persons}"
ItemTemplate="{StaticResource PeopleDataTemplate}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
Name="listOfPeople">
</ListBox>
Person
类包含两个属性:
public string FirstName { get; set; }
public string LastName { get; set; }
XAML:
<UserControl.Resources>
<DataTemplate x:Key="PeopleDataTemplate">
<StackPanel>
<Image
Width="75"
Height="75"
Source="{Binding Picture}">
</Image>
<TextBlock FontSize="14" TextWrapping="Wrap" Text="{Binding Name}" />
<Button Command="{Binding DataContext.AddCommand , ElementName=main}" Content="Add" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
如果我单击Image
,则ListBoxItem
被选中,但是如果我单击Button
,则ListBoxItem
未被选中。为什么?
答案 0 :(得分:1)
为什么没有选择该项目?
TL; DR:因为鼠标按下事件由Button
处理,并且从未到达ListBoxItem
。
触发每个IsSelected
的{{1}}属性的是ListBoxItem
路由事件declared on UIElement
,其事件被MouseRightButtonDownEvent
here覆盖。但是,此ListBoxItem
是bubbling routed event,这意味着它会爬到可视树上,直到被其标记为 handled 为止
MouseDownEvent
,则Image
会收到Image
,但不会处理。同样的故事,它最多可以冒充MouseDown
。最多可以冒充StackPanel
。宾果游戏,在那里处理它并在父项ListBoxItem
上调用一个方法,将项目标记为选中。ListBox
,则Button
会收到Button
事件,并立即将其标记为MouseDown
here。事件传播已停止,事件再也不会达到Handled
为止,永远不会被选中。如何解决这个问题?
MVVM方式
在您的ListBoxItem
实现中,添加一些代码以将AddCommand
属性更改为IsSelected
。由于您绑定到true
,因此将选择您的IsSelected
。
XAML方式
向ListBoxItem
添加Click
事件处理程序,以将其父项Button
手动标记为ListBoxItem
。
正如@Sinatr所指出的,您还可以对焦点事件做出反应,以选择任何获得焦点的项目。订阅每个Selected
的{{1}}事件,并订阅find的父GotFocus
(您在其中调用StackPanel
)并找到父{{ 1}}(您将其称为ListBox
)。
答案 1 :(得分:1)
最简单的解决方案是向ListBox.ItemContainerStyle
添加相应的触发器以委派焦点:
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>