扩展名为ListBoxItem不会触发选择

时间:2013-01-25 12:47:56

标签: wpf xaml

我使用ListBox ListBoxItem DataTemplate使用Expander作为其容器。问题是,Expander似乎正在吃掉Click事件(确切地说是HeaderSite的{​​{1}}部分),如果我点击,我永远不会得到ExpanderSelectedItem上(但如果您点击Expander本身就有效。)

如何让ListBoxItemExpander很好地合作?

这是一个简化的Xaml,可以重现问题(不需要代码):

修改代码已更新,以便更接近我的实际模板,但屏幕截图仍然来自之前的版本(问题相同 - 这只是为了澄清第一个答案的问题)

ListBox

屏幕截图是预编辑的

点击<Window x:Class="ListBoxSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <StackPanel> <TextBlock> <Run Text="Selected Item" /> <Run Text="{Binding ElementName=ListBox, Path=SelectedItem}" /> </TextBlock> <ListBox x:Name="ListBox"> <ListBoxItem> <Expander Header="Expandable Stuff 1"> <ListBox> <ListBoxItem>1.1</ListBoxItem> <ListBoxItem>1.2</ListBoxItem> </ListBox> </Expander> </ListBoxItem> <ListBoxItem> <Expander Header="Expandable Stuff 2"> <ListBox> <ListBoxItem>2.1</ListBoxItem> <ListBoxItem>2.2</ListBoxItem> </ListBox> </Expander> </ListBoxItem> </ListBox> </StackPanel> </Window> 生成ListBoxItem

Clicking on <code>ListBoxItem</code> resulting a <code>SelectedItem</code>

单击Expander导致 SelectedItem更新(点击扩展器1上显示为虚线轮廓):

Clicking on Expander resulting no <code>SelectedItem</code> update

2 个答案:

答案 0 :(得分:11)

如果没有代码,你可以这样做

<ListBox.ItemContainerStyle>
    <Style>
        <Style.Triggers>
            <EventTrigger RoutedEvent="Control.PreviewMouseLeftButtonDown">
                <BeginStoryboard>
                    <Storyboard Storyboard.TargetProperty="(Selector.IsSelected)">
                        <BooleanAnimationUsingKeyFrames Duration="0:0:0">
                            <DiscreteBooleanKeyFrame Value="True" />
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>

答案 1 :(得分:7)

以下代码似乎与缺点(或可能是优势)一起工作,每次只有选定项目将被删除。

将以下2个属性应用于2 Expander s

IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}"
IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}"

通过绑定IsHitTestVisible,它允许Expander中包含的元素与之交互。

导致:

            <ListBox x:Name="ListBox" IsSynchronizedWithCurrentItem="True">
                <ListBoxItem>
                    <Expander Header="Expandable Stuff 1" IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
                        1
                    </Expander>
                </ListBoxItem>
                <ListBoxItem>
            <Expander Header="Expandable Stuff 2" IsHitTestVisible="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
                        2
                    </Expander>
                </ListBoxItem>
            </ListBox>

代码背后的另一个解决方案就是这样:

            <ListBox x:Name="ListBox" IsSynchronizedWithCurrentItem="True">
                <ListBoxItem>
                    <Expander Header="Expandable Stuff 1" IsHitTestVisible="False" IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
                <StackPanel IsHitTestVisible="True">
                    <Label Content="1"/>
                </StackPanel>
            </Expander>
                </ListBoxItem>
                <ListBoxItem>
            <Expander Header="Expandable Stuff 2" ButtonBase.Click="Expander_Click_1" Tag="{Binding  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}">
                2                     
            </Expander>
                </ListBoxItem>
            </ListBox>

代码背后:

    private void Expander_Click_1(object sender, RoutedEventArgs e)
    {
        if (sender is Expander)
        {
            Expander senderExp = (Expander)sender;
            object obj = senderExp.Tag;
            if (obj is ListBoxItem)
            {
                ((ListBoxItem)obj).IsSelected = true;
            }
        }            
    }