c# - 如何在 XAML 中访问父模板样式的元素?

标签 c# wpf xaml

我在访问 WPF 中父模板样式的命名元素时遇到问题。

我有一个按钮的自定义控件(按 this StackOverflow question 编写):

自定义按钮.xaml:

<ResourceDictionary ...>
<Style x:Key="ButtonCustomStyle" TargetType="{x:Type local:ImageButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <Grid>
                    <Image Source="{TemplateBinding Image}" Stretch="Fill" x:Name="CurrentImage"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="CurrentImage" Property="Source" Value="{Binding ImageHover, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MainWindow.xaml:

<Window ...>
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="CustomButton.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource ButtonCustomStyle}"/>
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <local:ImageButton Image="\Images\image.png" ImageHover="\Images\image_hover.png" Width="20" Height="20"/>
</Grid>

ImageButton 继承 Button,并且 ImageImageHover 被定义为依赖属性。这段代码运行良好并且达到了预期的效果。

现在,我想为单个特定按钮扩展此模板样式,添加一个额外的触发器来更改按钮的图像。我正在尝试执行以下操作:

<Window...>
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="CustomButton.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource ButtonCustomStyle}"/>
        <Style TargetType="{x:Type local:ImageButton}"
               BasedOn="{StaticResource ButtonCustomStyle}"
               x:Key="Disableable">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter TargetName="CurrentImage" Property="Source" Value="\Images\disabled.png"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <local:ImageButton Image="\Images\image.png" ImageHover="\Images\image_hover.png" Width="20" Height="20"/>
    <local:ImageButton Style="{StaticResource Disableable}" Image="\Images\image.png" ImageHover="\Images\image_hover.png" Width="20" Height="20"/>
</Grid>

但是 Visual Studio 强调了新的 setter 行并显示“无法识别名称“CurrentImage””

有办法改变 CurrentImage 元素吗?

最佳答案

I am having trouble accessing a named element of a parent template style in WPF.

这是不可能的。您不能将一个 ControlTemplate 建立在另一个 ControlTemplate 之上。

如果您希望 setter 能够找到 CurrentImage,您恐怕必须在派生 Style 中从头开始重新定义整个 ControlTemplate在基本 Style 的模板中定义的 元素。

WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?

但是您应该能够使用设置控件本身的 Image 属性的 Style 触发器,而不是使用 ControlTemplate 触发器而不是在模板中设置 Image 元素的 Source 属性:

<Style x:Key="ButtonCustomStyle" TargetType="{x:Type local:ImageButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <Grid>
                    <Image Source="{TemplateBinding Image}" Stretch="Fill" x:Name="CurrentImage"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Image" Value="{Binding ImageHover, RelativeSource={RelativeSource Self}}"/>
        </Trigger>
    </Style.Triggers>
</Style>

<Style TargetType="{x:Type local:ImageButton}"
               BasedOn="{StaticResource ButtonCustomStyle}"
               x:Key="Disableable">
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Image" Value="\Images\disabled.png"/>
        </Trigger>
    </Style.Triggers>
</Style>

关于c# - 如何在 XAML 中访问父模板样式的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45676416/

相关文章:

c# - 如何在 PictureBox 中平移图像

c# - DateTimeFormatInfo.InvariantInfo 与 CultureInfo.InvariantCulture

wpf - 在 WPF 用户控件上使用非简单类型的依赖属性的模式

c# - 在开头引号旁边使用大括号时出现 HeaderStringFormat 问题

c# - uwp 标题栏中的后退按钮不可见

c# - 如何在 C# 中使用 linq 检查列表中是否存在两个值

c# - 方法 'btnLoginTest_Click' 没有重载需要 0 个参数

wpf - View 模型的数据网格行选择/焦点

wpf - 要以编程方式填充的彩色文本 block

wpf - 绑定(bind)到父 ListViewItem 的 IsSelected 属性