将 MenuItem 图标颜色绑定到 MenuItem 的前景

问题描述 投票:0回答:1

问题

我有一个带有控制模板的

MenuItem
,可以更改
MenuItem
Foreground
,如下所示:

<ControlTemplate TargetType="MenuItem">
    <StackPanel Background="{Binding Background}" Orientation="Horizontal">
        <ContentPresenter Content="{TemplateBinding Icon}"/>
        <TextBlock Text="{TemplateBinding Header}"/>
    </StackPanel>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Foreground" Value="Red"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

我想将图标的颜色绑定到该前景色。在这种情况下,图标只是一个圆圈。我尝试了以下绑定:

<MenuItem Header="Sub">
    <MenuItem.Icon>
        <Ellipse Width="16" Height="16" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
    </MenuItem.Icon>
</MenuItem>

但是,这会在应用程序启动时出现以下绑定错误,并且椭圆最终不会被渲染:

System.Windows.Data 错误:4:找不到引用“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.MenuItem',AncestorLevel='1'' 进行绑定的源。 BindingExpression:Path=前景;数据项=空;目标元素是“椭圆”(名称=“”);目标属性是“填充”(类型“画笔”)

我还尝试在图标中放置一个虚拟元素,以传播前景并绑定到此:

<MenuItem.Icon>
    <Grid>
        <TextBlock Name="foregroundCapture"/>
        <Ellipse Width="16" Height="16" Fill="{Binding Foreground, ElementName=foregroundCapture}"/>
    </Grid>
</MenuItem.Icon>

但这给出了类似的错误:

System.Windows.Data 错误:4:找不到引用“ElementName=foregroundCapture”的绑定源。 BindingExpression:Path=前景;数据项=空;目标元素是“椭圆”(名称=“”);目标属性是“填充”(类型“画笔”)

如何才能使绑定生效?仅供参考,图标最终将是资源字典中的一个对象。因此它将无法访问实际的菜单项。

替代解决方案

我可以想到几个替代解决方案。但实际上他们都不是很好:

  1. 创建具有
    MouseOverIcon
    属性的 MenuItem 子类并让触发器使用它。
  2. 为每个图标创建自定义控件,并传播
    Foreground
    属性。这将允许直接在控件内进行直接绑定。

完整示例

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="MenuItem">
            <Style.Triggers>
                <Trigger Property="Role" Value="SubmenuItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="MenuItem">
                                <StackPanel Background="{Binding Background}" Orientation="Horizontal">
                                    <ContentPresenter Content="{TemplateBinding Icon}"/>
                                    <TextBlock Text="{TemplateBinding Header}"/>
                                </StackPanel>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="true">
                                        <Setter Property="Foreground" Value="Red"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>

            </Style.Triggers>
        </Style>
    </Window.Resources>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="Header">
                <MenuItem Header="Sub">
                    <MenuItem.Icon>
                        <Grid>
                            <TextBlock Name="foregroundCapture"/>
                            <Ellipse Width="16" Height="16" Fill="{Binding Foreground, ElementName=foregroundCapture}"/>
                        </Grid>
                    </MenuItem.Icon>
                </MenuItem>
            </MenuItem>
        </Menu>

        <Grid>
        </Grid>
    </DockPanel>

</Window>
wpf xaml data-binding
1个回答
0
投票

你可以尝试这样的绑定:

<Ellipse Width="16" Height="16" Fill="{Binding RelativeSource={RelativeSource Mode=Self}, Path=(TextElement.Foreground)}"/>
© www.soinside.com 2019 - 2024. All rights reserved.