WPF访问派生类中唯一的单实例依赖属性 [英] WPF accesses only single instance of derived class with dependency property
问题描述
我从键产生了依赖属性的简单类:
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屋!