WPF中TreeViewItem和ListViewItem添加MouseLeftButtonDown事件后都用不了,这是怎么回事呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF中TreeViewItem和ListViewItem添加MouseLeftButtonDown事件后都用不了,这是怎么回事呢?相关的知识,希望对你有一定的参考价值。

ViewItem要怎么才能用MouseLeftButtonDown MouseDown 这类事件呢?

参考技术A 的确是有这么一回事,其实它并非不能用,只是部分功能不能实现,比如弹出对话框,这时你用MouseUp事件就好了,但有些事情可以做,比如改变一些bool值,改属性等,我做过一个按住拖动的例子,就用到MouseDown来改变鼠标样子。 参考技术B Mouse.MouseLeftButtonDown的路由事件可以用啊 参考技术C 可以用PreviousMouseLeftButtonDown试试追问

可以了,但是为什么呢?

追答

直接使用MouseLeftButtonDown,由于路由的原因,应该是被别的事件吃掉了

本回答被提问者采纳

WPF 如果选中它,则只保留一个 TreeViewItem 展开,折叠其他的,除非它是 Selected TreeViewItem 的祖先

【中文标题】WPF 如果选中它,则只保留一个 TreeViewItem 展开,折叠其他的,除非它是 Selected TreeViewItem 的祖先【英文标题】:WPF Keep only one TreeViewItem expanded if it is selected, collapse the others unless it is the ancestor of the Selected TreeViewItem 【发布时间】:2021-11-08 04:37:23 【问题描述】:

我有一个带有自定义样式的 TreeViewItem,我希望它具有如下行为,因此我想将其设置为我的 WPF 应用程序中的侧边菜单。问题是我只想将一个 TreeViewItem 保持为展开状态,而其他的则折叠起来,只要它们不是所选树的祖先。 例如,如果我在 Mammal 中选择 Cat,Mammal 显然也应该被扩展,但不是 Insects。如果我选择非洲,则必须扩大非洲和大陆,而必须折叠美洲,欧洲和亚洲。 还发生了一些奇怪的事情,SelectedItemChanged 事件没有触发,所以在选择新的 TreeViewItem 时 IsSelected 属性没有改变,所以我保留了应用于 TreeViewItem 的样式。

自定义样式

        <Style x:Key="TreeViewExpanderHeaderStyle" TargetType="x:Type ToggleButton">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="x:Type ToggleButton">
                        <Border Background="TemplateBinding Background">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="auto"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <ContentPresenter Grid.Column="1" Content="TemplateBinding Content"
                                              ContentTemplate="TemplateBinding ContentTemplate"
                                              ContentStringFormat="TemplateBinding ContentStringFormat"
                                              ContentTemplateSelector="TemplateBinding ContentTemplateSelector"
                                              VerticalAlignment="Center"
                                              Margin="0,0,16,0" />
                                <ToggleButton Grid.Column="2"
                                          VerticalAlignment="Center"
                                          Foreground="TemplateBinding Foreground" x:Name="Expander" Visibility="Binding HasItems, Converter=StaticResource BoolToVisibilityConverter, RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=x:Type TreeViewItem"
                                          IsChecked="Binding Path=IsChecked, Mode=TwoWay, RelativeSource=RelativeSource TemplatedParent">
                                    <ToggleButton.Style>
                                        <Style TargetType="x:Type ToggleButton">
                                            <Setter Property="Template">
                                                <Setter.Value>
                                                    <ControlTemplate TargetType="x:Type ToggleButton">
                                                        <Border Background="Transparent">
<Path Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" Opacity=".38" x:Name="ExpandPath" RenderTransformOrigin="0.5,0.5" Height="24" Width="24" Fill="TemplateBinding Foreground"/>

                                                        </Border>
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </ToggleButton.Style>
                                </ToggleButton>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="MyTreeViewItemFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style TargetType="x:Type TreeViewItem">
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="BorderBrush" Value="Gray"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="HorizontalContentAlignment" Value="Binding HorizontalContentAlignment, RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"/>
            <Setter Property="VerticalContentAlignment" Value="Binding VerticalContentAlignment, RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"/>
            <Setter Property="Padding" Value="8" />
            <Setter Property="FocusVisualStyle" Value="StaticResource MyTreeViewItemFocusVisual"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="x:Type TreeViewItem">
                        <Border BorderThickness="TemplateBinding BorderThickness" BorderBrush="TemplateBinding BorderBrush">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0:0:0.6"/>
                                    </VisualStateGroup.Transitions>
                                    <VisualState Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="HeaderSite"
                                                         Storyboard.TargetProperty="Opacity"
                                                         To="0.18" Duration="0"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState Name="Unselected"/>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ExpansionStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0" To="Expanded">
                                            <VisualTransition.GeneratedEasingFunction>
                                                <CubicEase EasingMode="EaseOut"/>
                                            </VisualTransition.GeneratedEasingFunction>
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost" Storyboard.TargetProperty="Visibility">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="x:Static Visibility.Visible" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsHost" To="1" Duration="0:0:0.3"/>
                                            </Storyboard>
                                        </VisualTransition>
                                        <VisualTransition GeneratedDuration="0" To="Collapsed">
                                            <VisualTransition.GeneratedEasingFunction>
                                                <CubicEase EasingMode="EaseOut"/>
                                            </VisualTransition.GeneratedEasingFunction>
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost" Storyboard.TargetProperty="Visibility">
                                                    <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="x:Static Visibility.Collapsed" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsHost" To="0" Duration="0:0:0.3"/>
                                            </Storyboard>
                                        </VisualTransition>
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="Expanded">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsHost" To="1" Duration="0"/>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="x:Static Visibility.Visible" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Collapsed">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsHost" To="0" Duration="0"/>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="x:Static Visibility.Hidden" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <DockPanel Background="TemplateBinding Background">
                                <ToggleButton Name="HeaderSite"
                                              DockPanel.Dock="Top"
                                              BorderThickness="0" Cursor="Hand"
                                              IsChecked="Binding Path=IsExpanded,RelativeSource=RelativeSource TemplatedParent"
                                              Style="StaticResource TreeViewExpanderHeaderStyle"
                                              Opacity=".87"
                                              Foreground="TemplateBinding Foreground"
                                              Content="TemplateBinding Header"
                                              ContentTemplate="TemplateBinding HeaderTemplate"
                                              ContentTemplateSelector="TemplateBinding HeaderTemplateSelector"
                                              ContentStringFormat="TemplateBinding HeaderStringFormat"/>
                                <Border Name="ContentSite" DockPanel.Dock="Bottom">
                                    <StackPanel x:Name="ItemsPanel" Margin="10 0 0 0">
                                        <StackPanel.Height>
                                            <MultiBinding Converter="StaticResource MathMlpMultipleConverter">
                                                <Binding ElementName="ItemsHost" Path="ActualHeight"/>
                                                <Binding ElementName="ItemsHost" Path="Opacity"/>
                                            </MultiBinding>
                                        </StackPanel.Height>
                                        <ItemsPresenter x:Name="ItemsHost" VerticalAlignment="Top" Opacity="0" Visibility="Collapsed"/>
                                    </StackPanel>
                                </Border>
                            </DockPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="TextElement.Foreground" Value="Red"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value=".56"/>
                            </Trigger>
                            
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>

            </Style.Triggers>
        </Style>

和树视图

        <TreeView SelectedItemChanged="TreeView_SelectedItemChanged">
            <TreeViewItem Header="Animals">
                <TreeViewItem Header="Mammals">
                    <TreeViewItem Header="Cat"/>
                    <TreeViewItem Header="Dog"/>
                    <TreeViewItem Header="Horse"/>
                </TreeViewItem>
                <TreeViewItem Header="Insects">
                    <TreeViewItem Header="Fly"/>
                    <TreeViewItem Header="Wasp"/>
                    <TreeViewItem Header="Bee"/>
                </TreeViewItem>
            </TreeViewItem>
            <TreeViewItem Header="Continents">
                <TreeViewItem Header="Africa">
                    <TreeViewItem Header="Angola"/>
                    <TreeViewItem Header="Congo"/>
                    <TreeViewItem Header="Egypth"/>
                    <TreeViewItem Header="S. Africa"/>
                </TreeViewItem>
                <TreeViewItem Header="America">
                    <TreeViewItem Header="USA"/>
                    <TreeViewItem Header="Canada"/>
                    <TreeViewItem Header="Mexico"/>
                    <TreeViewItem Header="Brazil"/>
                </TreeViewItem>
                <TreeViewItem Header="Europe">
                    <TreeViewItem Header="UK"/>
                    <TreeViewItem Header="Spain"/>
                    <TreeViewItem Header="France"/>
                    <TreeViewItem Header="Italy"/>
                </TreeViewItem>
                <TreeViewItem Header="Asia">
                    <TreeViewItem Header="China"/>
                    <TreeViewItem Header="Korea"/>
                    <TreeViewItem Header="Japan"/>
                    <TreeViewItem Header="Viet Nam"/>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>

【问题讨论】:

【参考方案1】:

我推荐使用这个简单的sn-p,一个简单的全局样式,可以转换成一个Behavior

<Window.Resources>
    <Style TargetType="x:Type TreeViewItem">
        <EventSetter Event="Expanded" Handler="TreeViewItem_Expanded"/>
    </Style>
</Window.Resources>

还有一个EventSetter 的处理程序

private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)

    var trvi = sender as TreeViewItem;
    //Using pattern matching
    //If parent is an ItemsControl and it's the current expanded item
    //That's a generic way to achieve such behavior
    if(trvi is Parent: ItemsControl parent, IsExpanded: true )
        foreach (TreeViewItem item in parent.Items)
            item.IsExpanded = false;

更新

由于您在选择另一个分支后要求折叠整个分支,因此您应该递归地遍历和折叠节点

private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)

    var trvi = sender as TreeViewItem;
    if (trvi is  Parent: ItemsControl parent, IsExpanded: true )
        foreach (TreeViewItem item in parent.Items)
            if (item != trvi && item.IsExpanded)
                CollapseBranch(item);




private static void CollapseBranch(TreeViewItem trvi)

    trvi.IsExpanded = false;

    foreach (TreeViewItem item in trvi.Items)
        CollapseBranch(item);

【讨论】:

以上是关于WPF中TreeViewItem和ListViewItem添加MouseLeftButtonDown事件后都用不了,这是怎么回事呢?的主要内容,如果未能解决你的问题,请参考以下文章

WPF程序里,有一个ListView,想要在其中拖动鼠标,生成一个矩形框,并选中矩形框中的item元素,该怎么做

在wpf中将treeviewitem显示为网格行

C# WPF TreeViewItem MouseDoubleClick 事件在 TreeViewItem 与 TreeViewItem.Header

WPF 如果选中它,则只保留一个 TreeViewItem 展开,折叠其他的,除非它是 Selected TreeViewItem 的祖先

WPF TreeViewItem 上下文菜单取消突出显示项

WPF中TreeViewItem和ListViewItem添加MouseLeftButtonDown事件后都用不了,这是怎么回事呢?