Wpf 使用依赖项属性在ControlTemplate触发器中设置值

Wpf 使用依赖项属性在ControlTemplate触发器中设置值,wpf,properties,triggers,controltemplate,Wpf,Properties,Triggers,Controltemplate,创建一个使用图像作为背景的按钮,当按下按钮时,另一个图像用于背景。继承自按钮并添加了两个ImageBrush类型的依赖属性,一个是PressedBackground。稍后将有一个枚举类型属性,用于选择将在“PresseImage”和“NormalImage”中加载哪一组图像资源 在controltemplate中,使用“IsPressed”的数据触发器,将背景属性设置为“PressedBackground”中的imagebrush。 但当运行时,按我们并没有背景,调试跟踪说“无法使用绑定检索值,

创建一个使用图像作为背景的按钮,当按下按钮时,另一个图像用于背景。继承自按钮并添加了两个ImageBrush类型的依赖属性,一个是PressedBackground。稍后将有一个枚举类型属性,用于选择将在“PresseImage”和“NormalImage”中加载哪一组图像资源

在controltemplate中,使用“IsPressed”的数据触发器,将背景属性设置为“PressedBackground”中的imagebrush。 但当运行时,按我们并没有背景,调试跟踪说“无法使用绑定检索值,并且不存在有效的回退值。”

问题是在onpressed数据触发器中将imagebrush从dependency属性加载到background属性中

自定义类代码段

public class QuantaImageButton : Button
{

    static QuantaImageButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(QuantaImageButton),
    new FrameworkPropertyMetadata(typeof(QuantaImageButton)));

    }


    public static readonly DependencyProperty PressedBackgroundProperty = DependencyProperty.Register(
        "PressedBackground", typeof(ImageBrush), typeof(QuantaImageButton), new PropertyMetadata(default(ImageBrush)));

    public ImageBrush PressedBackground
    {
        get { return (ImageBrush) GetValue(PressedBackgroundProperty); }
        set { SetValue(PressedBackgroundProperty, value); }
    }

    // other dependency properties
}
风格是:

<Style x:Key="BtnQuanta" TargetType="controls:QuantaImageButton">
    <Setter Property="PressedBackground" Value="{StaticResource BtnMenuMediumDownImage}"/>
    <Setter Property="Background" Value="{StaticResource BtnMenuMediumUpImage}"/>
    <Setter Property= "Width" Value="500" />
    <Setter Property="Height" Value="470"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="52"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template" Value="{StaticResource QuantaBtnControlTemplate}"/>
</Style>


<ControlTemplate x:Key="QuantaBtnControlTemplate" TargetType="{x:Type    controls:QuantaImageButton}">
    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="{Binding PressedBackground, RelativeSource={RelativeSource TemplatedParent} }"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

我找到了答案-正如调试文本所示-它找不到属性。绑定不正确-我已将其更改为:

 <ControlTemplate.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="{Binding PressedBackground, RelativeSource={RelativeSource Self} }"/>
        </Trigger>
    </ControlTemplate.Triggers>

对于不具有新属性的本地对象(而不是TemplateParent),RelativeSource需要是{RelativeSource Self}


作为一个“老”Winforms的家伙,转到WPF——如果任何人都有关于这种绑定的更多解释以及如何使用它的链接,这将是一个很大的帮助。

如果您添加
TargetName=“border”
将背景应用到模板内的边框,那么
{relativesourcetemplatedparent}
工作:

<ControlTemplate.Triggers>
    <Trigger Property="IsPressed" Value="True">
        <Setter TargetName="border" Property="Background" 
                Value="{Binding Path=PressedBackground, RelativeSource={RelativeSource TemplatedParent} }"/>
    </Trigger>
</ControlTemplate.Triggers>


添加TargetName会更改绑定的目标,显然会影响相对资源的分辨率。但是,我无法在文档中的任何地方指出这一细微差别。为什么不使用
静态资源
?在您的样式中使用对静态资源的引用,并动态更改它。另外,请查看
输出
窗口将为您提供它实际查找您指向的资源的位置信息。我们有大约40种不同的按钮样式,因此这将涉及40种不同的样式,我们需要一种样式和一个模板,我们使用枚举依赖项属性设置“按钮样式”,后面的代码在两个imagebrush属性—我需要知道如何访问控件模板中的依赖属性值—正确地说,在这种情况下,您可以使用
BasedOn
,让所有样式都意识到这一点。我不知道为什么您坚持要为一个按钮创建它已经拥有的功能。我想我这里缺少了更大的图片,但如果y你想想你在用这个按钮做什么,没有什么是不存在的。资源类型是image brush,如果样式设置了它的背景属性,它就会工作-所以我知道资源是ok的。按下按钮时VS debug会显示这一点