在ResourceDictionary中通过ControlTemplate的菜单项样式不能正确应用

本文关键字:不能 样式 应用 菜单项 ResourceDictionary ControlTemplate | 更新日期: 2023-09-27 18:19:25

我有一个按钮,它的XAML是这样的

<Button x:Name="Button2" Style="{StaticResource User_Hyperlink_Button}" Tag="123456789.XAML" Width="86" Height="30" Margin="26,327,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Button2" />

Button的样式在ResourceDictionary中定义,如下所示

<Style x:Key="User_Hyperlink_Button" TargetType="{x:Type Button}">              
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">        
        <Button Style="{DynamicResource App_button}" >
          <Hyperlink Style="{DynamicResource Button_LinkForeground}" NavigateUri="{Binding Path=Tag, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}">
            <InlineUIContainer>
              <TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
            </InlineUIContainer>
          </Hyperlink>
        </Button>
      </ControlTemplate>
    </Setter.Value>
  </Setter>     
</Style>

在这一切都工作得很好,但当我做同样的菜单项的文本为菜单项消失。

菜单项的示例如下

<MenuItem x:Name="MenuItem1" Style="{StaticResource User_Hyperlink_MenuItem}" Tag="123456789.XAML" Header="MenuItem1" />

风格是这样的

<Style x:Key="User_Hyperlink_MenuItem" TargetType="{x:Type MenuItem}">              
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type MenuItem}">        
        <MenuItem Style="{DynamicResource App_MenuItem}"  >
          <Hyperlink Style="{DynamicResource Menu_LinkForeground}" NavigateUri="{Binding Path=Tag, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}">
            <InlineUIContainer>
              <TextBlock Text="{Binding Path=Header, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
            </InlineUIContainer>
          </Hyperlink>
        </MenuItem>
      </ControlTemplate>
    </Setter.Value>
  </Setter>     
</Style>

我也改变了样式,像这样

...
<TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent, AncestorLevel=0}}" />
...

,但它不工作。我需要通过修改样式来解决这个问题,并且由于某些限制,不能更改菜单项的xaml。

更新1

我需要使MenuItem文本出现在它上面。文本在TextBlock中,但它的值来自MenuItem的Content属性。MenuItem没有Content属性,而是有Items Collection,这就是为什么文本不显示的原因。而在按钮的情况下,一切都在工作链接,文本所有。

我正在松散的XAML工作,所以我必须使用超链接链接。无需担心递归或继承,因为这不是问题。问题只是MenuItem没有Content属性,所以需要通过获取Item[0]来解决这个问题。

更新2

我还提供了其他参考资料

<Style x:Key="App_MenuItem" TargetType="{x:Type MenuItem}">
 <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="Background" Value="#FF015DAB"/>
 <Setter Property="Foreground" Value="White"/>
 <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
 <Style.Triggers>
   <Trigger Property="Role" Value="TopLevelHeader">
     <Setter Property="Margin" Value="0,1,0,1"/>
     <Setter Property="Padding" Value="6,3,6,3"/>
     <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="TopLevelItem">
      <Setter Property="Margin" Value="0,1,0,1"/>
      <Setter Property="Padding" Value="6,3,6,3"/>
      <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="SubmenuHeader">
      <Setter Property="DockPanel.Dock" Value="Top"/>
      <Setter Property="Padding" Value="0,2,0,2"/>
      <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   </Trigger>
   <Trigger Property="Role" Value="SubmenuItem">
      <Setter Property="DockPanel.Dock" Value="Top"/>
      <Setter Property="Padding" Value="0,2,0,2"/>
   </Trigger>
 </Style.Triggers>
</Style>
<Style x:Key="Menu_LinkForeground" TargetType="{x:Type Hyperlink}">
 <Setter Property="Foreground" Value="White" />
 <Setter Property="TextDecorations" Value="None" />
</Style>

在ResourceDictionary中通过ControlTemplate的菜单项样式不能正确应用

您使用的菜单项样式不正确。样式的模板不能引用对象本身,因为它创建了一个循环引用。只需在控件模板中使用超链接作为根可视化。

更新1 -我在说引用控件本身从其模板不工作。它的工作原理。它注入了在默认模板中写入的自定义内容。

这仍然没有多大意义。


下面是MenuItem的工作版本(注意,我从模板中剥离了所有资源,因为我没有它们)。只要一个一个地添加你的资源,看看什么时候它会停止工作。

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <Style x:Key="User_Hyperlink_MenuItem" TargetType="{x:Type MenuItem}">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type MenuItem}">
                            <MenuItem>
                                <Button>ABC</Button>
                            </MenuItem>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <MenuItem Style="{StaticResource User_Hyperlink_MenuItem}">A</MenuItem>        
    </Grid>
</Window>

作为参考,下面是默认菜单项的样式:
<Style TargetType="{x:Type MenuItem}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib">
    <Style.Triggers>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        7,2,8,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=TopLevelHeaderTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.TopLevelHeader" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        7,2,8,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=TopLevelItemTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.TopLevelItem" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        2,3,2,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Setter Property="Control.Template">
                <Setter.Value>
                    <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=SubmenuHeaderTemplateKey}" />
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.SubmenuHeader" />
                </Trigger.Value>
            </Trigger>
        <Trigger Property="MenuItem.Role">
            <Setter Property="Control.Padding">
                <Setter.Value>
                    <Thickness>
                        2,3,2,3</Thickness>
                    </Setter.Value>
                </Setter>
            <Trigger.Value>
                <x:Static Member="MenuItemRole.SubmenuItem" />
                </Trigger.Value>
            </Trigger>
        </Style.Triggers>
    <Style.Resources>
        <ResourceDictionary />
        </Style.Resources>
    <Setter Property="Control.HorizontalContentAlignment">
        <Setter.Value>
            <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
    <Setter Property="Control.VerticalContentAlignment">
        <Setter.Value>
            <Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
    <Setter Property="Panel.Background">
        <Setter.Value>
            <SolidColorBrush>
                #00FFFFFF</SolidColorBrush>
            </Setter.Value>
        </Setter>
    <Setter Property="ScrollViewer.PanningMode">
        <Setter.Value>
            <x:Static Member="PanningMode.Both" />
            </Setter.Value>
        </Setter>
    <Setter Property="Stylus.IsFlicksEnabled">
        <Setter.Value>
            <s:Boolean>
                False</s:Boolean>
            </Setter.Value>
        </Setter>
    <Setter Property="Control.Template">
        <Setter.Value>
            <DynamicResource ResourceKey="{ComponentResourceKey TypeInTargetAssembly=MenuItem, ResourceId=SubmenuItemTemplateKey}" />
            </Setter.Value>
        </Setter>
    </Style>