英文:
How to update MenuItem Control Template in c# wpf
问题
我是新手c# wpf应用程序,我试图在c# wpf应用程序中使用样式更新默认的MenuItem控件模板。我试图在xaml中使用Tag来更新材料设计图标Kind为User。
<MenuItem Header="测试菜单项" Style="{StaticResource MenuItemCustomStyle}" Tag="User"/>
在样式中,我使用模板绑定来更新PackIcon的Kind。
<Style x:Key="MenuItemCustomStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Height" Value="40"/>
    <Setter Property="HorizontalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type MenuItem}">
                <StackPanel x:Name="stackpanel" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Stretch">
                    <materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Kind="{TemplateBinding Tag}" Margin="10,5,5,10" Width="25"/>
                    <TextBlock x:Name="menuItemTitle" Foreground="Gray" FontSize="16" Margin="0,7" Text="{TemplateBinding Header}"/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Foreground" TargetName="menuItemIcon" Value="White"/>
                        <Setter Property="Background" TargetName="stackpanel" Value="DarkGray"/>
                        <Setter Property="Foreground" TargetName="menuItemTitle" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
我该如何在c# wpf应用程序中实现它?我是否漏掉了什么?我应该使用依赖属性来实现吗?如果是的话,如何做到?
英文:
I am new to c# wpf application and I am trying to update default MenuItem control template using style in c# wpf application. I am trying to update material design icon Kind to User using Tag in xaml.
<MenuItem Header="Test Menu Item" Style="{StaticResource MenuItemCustomStyle}" Tag="User"/>
In the styles I am using template binding to update Kind of PackIcon.
        <Style x:Key="MenuItemCustomStyle" TargetType="{x:Type MenuItem}">
        <Setter Property="Height" Value="40"/>
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
                    <StackPanel x:Name="stackpanel" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Stretch">
                        <materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Kind="{TemplateBinding Tag}" Margin="10,5,5,10" Width="25"/>
                        <TextBlock x:Name="menuItemTitle" Foreground="Gray" FontSize="16" Margin="0,7" Text="{TemplateBinding Header}"/>
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" TargetName="menuItemIcon" Value="White"/>
                            <Setter Property="Background" TargetName="stackpanel" Value="DarkGray"/>
                            <Setter Property="Foreground" TargetName="menuItemTitle" Value="White"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
How do I achieve it in c# wpf application. Am I missing something. Should I be using Dependency property to achieve it. If yes, How?
答案1
得分: 1
RelativeSource="{RelativeSource TemplatedParent}"将绑定的源设置为父级,即此情况下的MenuItem。这允许您在控件模板中访问MenuItem的属性。
<materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Margin="10,5,5,10" Width="25">
    <materialDesign:PackIcon.Kind>
        <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Tag"/>
    </materialDesign:PackIcon.Kind>
</materialDesign:PackIcon>
完整示例:
<Window x:Class="WpfApp12.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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style x:Key="MenuItemCustomStyle" TargetType="{x:Type MenuItem}">
            <Setter Property="Height" Value="40"/>
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalAlignment" Value="Stretch"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <StackPanel x:Name="stackpanel" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Stretch">
                            <materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Margin="10,5,5,10" Width="25">
                                <materialDesign:PackIcon.Kind>
                                    <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Tag"/>
                                </materialDesign:PackIcon.Kind>
                            </materialDesign:PackIcon>
                            <TextBlock x:Name="menuItemTitle" Foreground="Gray" FontSize="16" Margin="0,7" Text="{TemplateBinding Header}"/>
                        </StackPanel>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" TargetName="menuItemIcon" Value="White"/>
                                <Setter Property="Background" TargetName="stackpanel" Value="DarkGray"/>
                                <Setter Property="Foreground" TargetName="menuItemTitle" Value="White"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <MenuItem Header="Test Menu Item" Style="{StaticResource MenuItemCustomStyle}" Tag="User"/>
    </Grid>
</Window>
英文:
RelativeSource="{RelativeSource TemplatedParent}" sets the source of the binding to the parent, which is the MenuItem in this case. This allows you to access properties of the MenuItem within the control template.
<materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Margin="10,5,5,10" Width="25">
<materialDesign:PackIcon.Kind>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Tag"/>
</materialDesign:PackIcon.Kind>
</materialDesign:PackIcon>
Full sample:
<Window x:Class="WpfApp12.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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="MenuItemCustomStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Height" Value="40"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<StackPanel x:Name="stackpanel" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Stretch">
<materialDesign:PackIcon x:Name="menuItemIcon" Height="25" Margin="10,5,5,10" Width="25">
<materialDesign:PackIcon.Kind>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Tag"/>
</materialDesign:PackIcon.Kind>
</materialDesign:PackIcon>
<TextBlock x:Name="menuItemTitle" Foreground="Gray" FontSize="16" Margin="0,7" Text="{TemplateBinding Header}"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" TargetName="menuItemIcon" Value="White"/>
<Setter Property="Background" TargetName="stackpanel" Value="DarkGray"/>
<Setter Property="Foreground" TargetName="menuItemTitle" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<MenuItem Header="Test Menu Item" Style="{StaticResource MenuItemCustomStyle}" Tag="User"/>
</Grid>
</Window>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论