简体   繁体   English

如何使WPF Listbox子datatemplate控件在单击时选择ListBoxItem容器?

[英]How make WPF Listbox child datatemplate controls select the ListBoxItem container when clicked?

I have a listbox and in the datatemplate I have an Expander. 我有一个列表框,在datatemplate中我有一个Expander。

If I click on the Expander Header, the expander expand the content zone but not make the parent ListBoxItem Selected. 如果我单击Expander Header,扩展器将展开内容区域,但不会使父ListBoxItem选中。

If I click on the Expanded Content Zone of the Expander, the parent ListBoxItem become selected. 如果我单击Expander的Expanded Content Zone,则会选择父ListBoxItem。

How to make that when clicking the expanderHeader, the content become expanded AND the parent listboxitem become selected? 单击expandderHeader时如何使内容扩展并且父列表框项被选中?

I realise that this question has been answered, but there is a much simpler way to achieve this desired result. 我意识到这个问题已得到解答,但有一种更简单的方法可以实现这个理想的结果。 You can add a Trigger to the ListBoxItem Style that will select the ListBoxItem whenever an element in its ItemTemplate has keyboard focus: 您可以向ListBoxItem Style添加一个Trigger ,只要其ItemTemplate的元素具有键盘焦点,它就会选择ListBoxItem

<Style.Triggers> 
  <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
    <Setter Property="IsSelected" Value="True"/> 
  </Trigger> 
</Style.Triggers>

For more information, view MSDN , or post1 or post2 . 有关更多信息,请查看MSDNpost1post2

I ran into the same issue and handled it by listening to the PreviewGotKeyboardFocus event on the ListBox. 我遇到了同样的问题并通过侦听ListBox上的PreviewGotKeyboardFocus事件来处理它。 When the focus changes walk the visual tree looking for a ListBoxItem and select it: 当焦点更改时,可视树会查找ListBoxItem并选择它:

    private void ListBox_PreviewGotKeyboardFocus( object sender, KeyboardFocusChangedEventArgs e )
    {
        if( e.NewFocus is FrameworkElement )
        {
            ListBoxItem item = ( e.NewFocus as FrameworkElement ).FindParent<ListBoxItem>();
            if( item != null && !item.IsSelected )
            {
                item.IsSelected = true;
            }
        }
    }

    public static T FindParent<T>( this FrameworkElement element ) where T : FrameworkElement
    {
        DependencyObject current = element;

        while( current != null )
        {
            if( current is T )
            {
                return ( T ) current;
            }

            current = VisualTreeHelper.GetParent( current );
        }

        return null;
    }

can't you use the Expanded event for that ? 你不能使用Expanded事件吗?

something like 就像是

<Expander Expanded="Expander_Expanded"

and

private void Expander_Expanded(object sender, RoutedEventArgs e)
{
    parentListBox.Focus();
}

something you can do is to bind the IsExpanded Property of the Expander directly with the IsSelected Property of the ListBoxItem. 您可以做的是将Expander的IsExpanded属性直接与ListBoxItem的IsSelected属性绑定。 But this means, that is you just select an item the expander gets expanded too... And it means too that unselected items are never expanded. 但这意味着,你只需选择扩展器扩展的项目......这也意味着未选择的项目永远不会扩展。

example: 例:

  <ListBox>
    <ListBox.ItemTemplate>
      <DataTemplate>
        <Expander IsExpanded="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}">
          <TextBlock Text="bla bla" />
        </Expander>
      </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Items>
      <DataObject />
      <DataObject />
    </ListBox.Items>
  </ListBox>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM