首页 > 解决方案 > 如何使单击 ListBoxItem 内的按钮选择项目?

问题描述

我有一个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>

如果我单击ImageListBoxItem则会被选中,但如果我单击ButtonListBoxItem则不会被选中。为什么?

标签: c#wpfxaml

解决方案


为什么项目没有被选中?

TL;DR:因为鼠标按下事件由 处理,Button并且永远不会到达ListBoxItem.

触发IsSelected每个属性的ListBoxItem声明MouseRightButtonDownEvent的路由事件,其处理被here覆盖。然而,这是一个冒泡的路由事件,这意味着它会爬上可视化树,直到标记为在途中被某物处理:UIElementListBoxItem MouseDownEvent

  • 如果您单击您的Image:Image接收MouseDown但不处理它。它冒泡StackPanel,同样的故事。气泡达ListBoxItem. 宾果游戏,它在那里处理并调用父项上的一个方法,ListBox将项目标记为选中。
  • 如果单击 yourButton然而:Button接收MouseDown事件并立即将其标记为Handled here。事件传播被停止,并且事件永远不会冒泡到ListBoxItem永远不会被选中的事件。

如何解决这个问题?

MVVM 方式

在您的AddCommand实现中,添加一些代码以将IsSelected属性更改为true. 由于您绑定到IsSelected,这将选择您的ListBoxItem.

XAML 方式

Click事件处理程序添加到Button以手动将其父标记ListBoxItemSelected.

正如@Sinatr 所指出的,您还可以对焦点事件做出反应以选择任何获得焦点的项目。例如,订阅GotFocus您每个人的事件StackPanel找到父级ListBox(您调用UnselectAll())并找到父级ListBoxItem(您调用Focus())。


推荐阅读