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

时间:2017-07-16 09:02:47

标签: wpf xaml data-binding

问题

我有一个MenuItem,其中包含一个控件模板,可以更改MenuItem' s 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:无法找到带引用的绑定源&#39; RelativeSource FindAncestor,AncestorType =&#39; System.Windows.Controls.MenuItem&#39;,AncestorLevel =&#39; 1& #39;&#39 ;. BindingExpression:路径=前景;的DataItem = NULL;目标元素是&#39; Ellipse&#39; (名称=&#39;&#39);目标财产是“填充”。 (键入&#39;刷&#39;)

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

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

但这会产生类似的错误:

  

System.Windows.Data错误:4:无法找到带引用的绑定源&#39; ElementName = foregroundCapture&#39;。 BindingExpression:路径=前景;的DataItem = NULL;目标元素是&#39; Ellipse&#39; (名称=&#39;&#39);目标财产是“填充”。 (键入&#39;刷&#39;)

如何使绑定工作?仅供参考,图标最后将成为资源字典中的对象。因此它无法访问实际的菜单项。

替代解决方案

我可以想到几种替代解决方案。但其中没有一个真的很好:

  1. 创建一个MenuItem的子类,该子类具有MouseOverIcon属性并使触发器使用它。
  2. 为每个图标创建自定义控件,其中传播了Foreground属性。这将允许直接在控件内直接绑定。
  3. 完整示例

    <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>
    

0 个答案:

没有答案