WPF访问派生类中唯一的单实例依赖属性 [英] WPF accesses only single instance of derived class with dependency property

查看:180
本文介绍了WPF访问派生类中唯一的单实例依赖属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从键产生了依赖属性的简单类:

I have a simple class derived from Button with a dependency property:

public sealed class CircleButton : Button
{
    public Visual Visual
    {
        get { return (Visual)GetValue(VisualProperty); }
        set { SetValue(VisualProperty, value); }
    }

    public static readonly DependencyProperty VisualProperty = DependencyProperty.Register("Visual", typeof(Visual), typeof(CircleButton));
}



我有以下样式为CircleButton:

I have the following style for the CircleButton:

<Style x:Key="CircleButtonStyle" TargetType="{x:Type controls1:CircleButton}">
    ...
    <Setter Property="Content">
        <Setter.Value>
            <Rectangle Style="{StaticResource CircleButtonRectangleStyle}"/>
        </Setter.Value>
    </Setter>
    ...
</Style>

在CircleButton风格引用的矩形风格被定义为:

The rectangle style referenced in the CircleButton style is defined as:

<Style x:Key="CircleButtonRectangleStyle" TargetType="{x:Type Rectangle}">
    <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Width, Converter={StaticResource ArithmeticConverter}}"/>
    <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Height, Converter={StaticResource ArithmeticConverter}}"/>
    <Setter Property="Fill" Value="White"/>
    <Setter Property="OpacityMask">
        <Setter.Value>
            <VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Visual}"/>
        </Setter.Value>
    </Setter>
</Style>



最后,我的XAML定义了三个CircleButton实例:

Finally, my XAML defines three CircleButton instances:

        <StackPanel Grid.Row="1" Grid.Column="2">
            <controls:CircleButton HorizontalAlignment="Center" VerticalAlignment="Center" Width="30.0" Height="30.0" 
                    Style="{DynamicResource CircleButtonStyle}" Command="{Binding Add}" ToolTip="Add new product filter." BorderBrush="White" BorderThickness="1" 
                                   Background="{DynamicResource AccentColorBrush}" Visual="{DynamicResource appbar_add}"/>
            <controls:CircleButton HorizontalAlignment="Center" VerticalAlignment="Center" Width="30.0" Height="30.0" 
                    Style="{DynamicResource CircleButtonStyle}" Command="{Binding Remove}" ToolTip="Remove product filter." BorderBrush="White" BorderThickness="1" 
                                   Background="{DynamicResource AccentColorBrush}" Visual="{DynamicResource appbar_minus}"/>
            <controls:CircleButton HorizontalAlignment="Center" VerticalAlignment="Center" Width="30.0" Height="30.0" 
                    Style="{DynamicResource CircleButtonStyle}" Command="{Binding Remove}" ToolTip="Remove product filter." BorderBrush="White" BorderThickness="1" 
                                   Background="{DynamicResource AccentColorBrush}" Visual="{DynamicResource appbar_music}"/>
        </StackPanel>



所有三个按钮显示,而且在序列中只有最后一个具有图像(它是正确的)。出现这种情况无论多少我的按钮添加。

All three buttons display, but only the last in the sequence has an image (it is the correct one). This occurs no matter how many buttons I add.

任何人都明白我失踪,我需要做什么来纠正呢?

Anyone see what I'm missing and what I need to do to correct it?

推荐答案

这不是很明显,但实际上你只定义的VisualBrush 的一个实例。这里将是 Setter.Value 元素的内容中只有一个副本。每次它被添加到您的圈子按钮之一时,它就会被拽出前一个。

It's not obvious, but in fact you're only defining one instance of VisualBrush. There will be exactly one copy of the content of that Setter.Value element. Each time it gets added to one of your circle buttons, it gets yanked out of the previous one.

尝试应用模板代替,并应用视觉刷在模板中的元素。在模板的元素的单独应用模板,每次创建。

Try applying a template instead, and apply that visual brush to an element in the template. Elements in a template are created individually every time the template is applied.

现在,你不能应用控件模板长方形。但是你可以将大量的模板来很多东西,所以没什么大不了的。

Now, you can't apply a ControlTemplate to a Rectangle. But you can apply lots of templates to lots of things, so no big deal.

这可能会奏效。 按钮 ContentControl中的子类,所以它有一个的ContentTemplate 属性,它被实例化,以显示无论你放在按钮内容属性。这种用法有点滑稽,因为它不显示内容 - 但你不使用内容

This might work. Button is a subclass of ContentControl so it's got a ContentTemplate property, which is instantiated to display whatever you put in the Button's Content property. This use is a little funny because it doesn't display the Content -- but you're not using Content.

<Style x:Key="CircleButtonStyle" TargetType="{x:Type controls1:CircleButton}">
    <!-- ... -->
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Rectangle
                    Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Width, Converter={StaticResource ArithmeticConverter}}"
                    Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Height, Converter={StaticResource ArithmeticConverter}}"
                    Fill="White"
                    >
                    <Rectangle.OpacityMask>
                        <VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls1:CircleButton}}, Path=Visual}"/>
                    </Rectangle.OpacityMask>
                </Rectangle>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>



但是,你知道什么类型的 ContentControl.Content 是什么?这是对象。你可以在那里什么东西,而的ContentTemplate 可以做任何事情与任何它找到喜欢的。我敢肯定,这会工作得很好,而且可能让您不用编写 CircleButton 子类都:

But you know what type ContentControl.Content is? It's Object. You can stuff anything in there, and the ContentTemplate can do whatever it likes with whatever it finds. I bet this would work just fine, and might save you having to write that CircleButton subclass at all:

<Style x:Key="CircleButtonStyle" TargetType="{x:Type Button}">
    <!-- ... -->
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Rectangle
                    Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Width, Converter={StaticResource ArithmeticConverter}}"
                    Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Height, Converter={StaticResource ArithmeticConverter}}"
                    Fill="White"
                    >
                    <Rectangle.OpacityMask>
                        <VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Content}"/>
                    </Rectangle.OpacityMask>
                </Rectangle>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- ... -->

<Button 
    Style="{DynamicResource CircleButtonStyle}" 
    Command="{Binding Remove}" 
    ToolTip="Remove product filter." 
    Content="{DynamicResource appbar_music}"
    />

这篇关于WPF访问派生类中唯一的单实例依赖属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆