如何通过 C# 而不是 XAML 为 TreeView 编写触发器和设置器

发布于 2024-12-28 05:37:05 字数 2672 浏览 2 评论 0原文

如何从代码隐藏而不是 XAML 将以下基于 XAML 的触发器添加到 TreeView。

<TreeView>
        <TreeView.Resources>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Header="Menu Item 1" />
                            <MenuItem Header="Menu Item 2" />
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.Resources>
        <TreeViewItem Header="Item 1">
            <TreeViewItem Header="Sub-Item 1"/>
        </TreeViewItem>
        <TreeViewItem Header="Item 2"></TreeViewItem>
    </TreeView>

WPF 的默认行为是在 ContextMenu 打开时将 TreeViewItem 更改为灰色,但与 WPF 中的几乎所有其他内容一样,您可以覆盖此设置:

创建附加属性 ContextMenuOpened 在 TreeViewItem 样式中,将 ContextMenuOpened 绑定到“ContextMenu.IsOpen” 添加一个触发器,当 ContextMenuOpened 和 IsSelected 均为 true 时更改画笔 这是附加属性:

public class TreeViewCustomizer : DependencyObject
{
  public static bool GetContextMenuOpened(DependencyObject obj) { return (bool)obj.GetValue(ContextMenuOpenedProperty); }
  public static void SetContextMenuOpened(DependencyObject obj, bool value) { obj.SetValue(ContextMenuOpenedProperty, value); }
  public static readonly DependencyProperty ContextMenuOpenedProperty = DependencyProperty.RegisterAttached("ContextMenuOpened", typeof(bool), typeof(TreeViewCustomizer));
}

这是样式中的设置器:

<Setter Property="my:TreeViewCustomizer.ContextMenuOpened"
        Value="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource Self}}" />

这是触发器:

<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="IsSelected" Value="true"/>
    <Condition Property="my:TreeViewCustomizer.ContextMenuOpened" Value="true"/>
  </MultiTrigger.Conditions>
  <Setter TargetName="Bd"
          Property="Background"
          Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
  <Setter Property="Foreground"
          Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</MultiTrigger>

我的应用程序中的所有树都是在运行时通过 C# 代码创建的。 我想通过 C# 代码完成上述所有工作,因为我在运行时创建了我的树 通过使用以下代码

TreeView _objTreeView =  new TreeView();

参考问题: WPF TreeViewItem 上下文菜单取消突出显示项目

How to Add following XAML based trigger to TreeView from Code behind rather than XAML.

<TreeView>
        <TreeView.Resources>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Header="Menu Item 1" />
                            <MenuItem Header="Menu Item 2" />
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.Resources>
        <TreeViewItem Header="Item 1">
            <TreeViewItem Header="Sub-Item 1"/>
        </TreeViewItem>
        <TreeViewItem Header="Item 2"></TreeViewItem>
    </TreeView>

WPF's default behavior is to change the TreeViewItem to gray when the ContextMenu opens, but like virtually everything else in WPF you can override this:

Create an attached property ContextMenuOpened
In the TreeViewItem Style, bind ContextMenuOpened to "ContextMenu.IsOpen"
Add a trigger that changes the brush when ContextMenuOpened and IsSelected are both true
Here's the attached property:

public class TreeViewCustomizer : DependencyObject
{
  public static bool GetContextMenuOpened(DependencyObject obj) { return (bool)obj.GetValue(ContextMenuOpenedProperty); }
  public static void SetContextMenuOpened(DependencyObject obj, bool value) { obj.SetValue(ContextMenuOpenedProperty, value); }
  public static readonly DependencyProperty ContextMenuOpenedProperty = DependencyProperty.RegisterAttached("ContextMenuOpened", typeof(bool), typeof(TreeViewCustomizer));
}

Here's the setter in the style:

<Setter Property="my:TreeViewCustomizer.ContextMenuOpened"
        Value="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource Self}}" />

Here's the trigger:

<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="IsSelected" Value="true"/>
    <Condition Property="my:TreeViewCustomizer.ContextMenuOpened" Value="true"/>
  </MultiTrigger.Conditions>
  <Setter TargetName="Bd"
          Property="Background"
          Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
  <Setter Property="Foreground"
          Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</MultiTrigger>

All trees in my application are created at Runtime through C# code.
I want to do all the above work throughC# code as I have created my tree at Runtime
by using following code

TreeView _objTreeView =  new TreeView();

Reference Question : WPF TreeViewItem Context Menu Unhighlights Item

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

携君以终年 2025-01-04 05:37:05

使用以下语句完成它

SolidColorBrush colorBrush = new SolidColorBrush(Colors.DodgerBlue); myTreeView.Resources.Add(SystemColors.ControlBrushKey, colorBrush);

:)

Done it using following statements

SolidColorBrush colorBrush = new SolidColorBrush(Colors.DodgerBlue); myTreeView.Resources.Add(SystemColors.ControlBrushKey, colorBrush);

:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文