0

有人可以帮我解决这个问题吗?我在 WPF 中有以下模板设置:

    <Style TargetType="{x:Type Label}" x:Key="NavLink">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate x:Name="NavLinkControlTemplate" TargetType="{x:Type Label}">
                    <Border x:Name="NavLinkBorder">
                        <ContentPresenter x:Name="NavLinkContent" Margin="4,4,4,4" />
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="NavLinkBorder" Property="Background" Value="#CCCCCC" />
                            <Setter Property="Cursor" Value="Hand" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter TargetName="NavLinkBorder" Property="Background" Value="#EAEAEA" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

当我的程序加载时,它会自动创建一个标签列表作为导航菜单。从上面可以看出,当鼠标悬停在其中一个标签上时,背景颜色会发生变化。唯一的问题是我还有一个应用于标签的上下文菜单,当我右键单击以将其调出时,标签背景会恢复其原始颜色,而不是保持 MouseOver 颜色。

我用谷歌搜索了大约一个小时左右,似乎找不到一个触发器属性来检查鼠标右键是否被按下,所以我假设没有。我在想也许我可以通过代码来实现这一点。

我已经尝试了以下代码,但我没有任何运气:

    // this event is being added to each label at runtime...
    tempLabel.MouseRightButtonUp += new MouseButtonEventHandler(NavLink_RightClicked);

    // this is the method that the right-click calls...
    private void NavLink_RightClicked(object sender, EventArgs e)
        {
            if (sender is Label)
            {
                currentContextLink = sender as Label;

                // the below line won't work because the ControlTemplate seems to be overwriting it...
                currentContextLink.Background = new SolidColorBrush(appFunctions.HexToColor("#FF0000"));
            }
        }

我也尝试将标签的父元素作为边框,但似乎由于它是通过模板设置的,标签的父元素实际上是我拥有的包含所有标签的 StackPanel。

有人可以帮我弄清楚如何访问边框并更改其背景颜色,或者指导我朝任何可能帮助我完成此任务的方向吗?

任何帮助是极大的赞赏!

4

3 回答 3

1

您可以添加一个额外的数据触发器来通过绑定检查 ContextMenu 的 IsOpen 属性。

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=ContextMenu.IsOpen}" Value="True">
    <Setter TargetName="NavLinkBorder"  Property="Background" Value="#CCCCCC" />
    <Setter Property="Cursor" Value="Hand" />
</DataTrigger>

您还可以摆脱 MouseOver="false" 触发器,只需将 NavLinkBorder 上的 Background="#EAEAEA" 设置为默认值,当没有触发器处于活动状态时它将接管。

或者,您可以切换边框颜色设置以使用模板绑定,这将有助于您的代码方法工作。无论如何,这是一个很好的做法,因为它使您的模板更加灵活,因为可以在各个 Label 实例上设置不同的背景值。这是添加了一些 TemplateBindings 和上下文菜单触发器的样式。

<Style TargetType="{x:Type Label}" x:Key="NavLink">
    <Setter Property="Background" Value="#EAEAEA" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate x:Name="NavLinkControlTemplate" TargetType="{x:Type Label}">
                <Border x:Name="NavLinkBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ContentPresenter x:Name="NavLinkContent" Margin="4,4,4,4" />
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="NavLinkBorder" Property="Background" Value="#CCCCCC" />
                        <Setter Property="Cursor" Value="Hand" />
                    </Trigger>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=ContextMenu.IsOpen}" Value="True">
                        <Setter TargetName="NavLinkBorder" Property="Background" Value="#CCCCCC" />
                        <Setter Property="Cursor" Value="Hand" />
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
于 2010-07-10T04:20:32.100 回答
0

以你的风格试试这个:

<EventTrigger RoutedEvent="MouseRightButtonUp">
    <BeginStoryboard>
        <Storyboard>
            <ColorAnimation To="#FF0000" Duration="0" Storyboard.TargetName="NavLinkBorder" Storyboard.TargetProperty="(Background).(Color)"  />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

请注意,<Trigger Property="IsMouseOver" Value="False">一旦鼠标移开,颜色就会变回#EAEAEA。如果您希望颜色“粘”,请ControlTemplate按以下方式修改:

<Border x:Name="NavLinkBorder">
    <Border x:Name="NavLinkInnerBorder" Background="Transparent" >
        <ContentPresenter x:Name="NavLinkContent" Margin="4,4,4,4" />
    </Border>
</Border>

...并将 ColorAnimation 更改为如下所示:

<ColorAnimation To="#FF0000" Duration="0" Storyboard.TargetName="NavLinkInnerBorder" Storyboard.TargetProperty="(Background).(Color)"  />
于 2010-07-09T19:19:51.530 回答
0

感谢您的帮助,但我对 WPF 有点陌生,对 RoutedEvents 不太熟悉。我按照您的建议添加了第一部分代码,但是当我运行它时,出现以下错误:

无法将属性“RoutedEvent”中的字符串“MouseRightButtonUp”转换为“System.Windows.RoutedEvent”类型的对象。RoutedEventConverter 无法从 System.String 转换。标记文件“MyProgram;component/frmmain.xaml”第 62 行位置 43 中的对象“System.Windows.EventTrigger”出错。

我的 XAML 样式代码现在如下所示:

    <Style TargetType="{x:Type Label}" x:Key="NavLink">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <Border x:Name="NavLinkBorder" Background="#CCCCCC">
                        <ContentPresenter x:Name="NavLinkContent" Margin="4,4,4,4" />
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="NavLinkBorder" Property="Background" Value="#CCCCCC" />
                            <Setter Property="Cursor" Value="Hand" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter TargetName="NavLinkBorder" Property="Background" Value="#EAEAEA" />
                        </Trigger>
                        <EventTrigger RoutedEvent="MouseRightButtonUp">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation To="#FF0000" Duration="0" Storyboard.TargetName="NavLinkBorder" Storyboard.TargetProperty="(Background).(Color)"  />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

而且,我之前没有发布过这个,但这就是生成我的标签的代码:

    Label tempLabel = new Label();
    tempLabel.Content = "My Link";
    tempLabel.ContextMenu = (ContextMenu)FindResource("NavContextMenu");
    tempLabel.FontSize = 12;
    tempLabel.Foreground = new SolidColorBrush(appFunctions.HexToColor("#000057"));
    tempLabel.Name = "myNavLink";
    tempLabel.Style = (Style)FindResource("NavLink");

    tempLabel.MouseLeftButtonUp += new MouseButtonEventHandler(NavLink_LeftClicked);
    tempLabel.MouseRightButtonUp += new MouseButtonEventHandler(NavLink_RightClicked);

    navPanel.Children.Add(tempLabel);

当我收到错误消息时,它会突出显示上述代码中的这一行:

    tempLabel.Style = (Style)FindResource("NavLink");

也许我没有正确附加标签的样式......?

于 2010-07-09T20:56:12.563 回答