WPF样式的引用类型DependencyProperty

问题描述:

我有WPF样式相关的问题。 让我们使用类(或准备这样)来包含DependencyProperty。WPF样式的引用类型DependencyProperty

public class MyProperty : DependencyObject 
{ 
    public static readonly DependencyProperty exampleValueProperty = DependencyProperty.Register("exampleValue", typeof(bool), typeof(MyProperty)); 

    public bool exampleValue 
    { 
     get { return (bool)this.GetValue(exampleValueProperty); } 
     set { this.SetValue(exampleValueProperty, value); } 
    } 
} 

public class MyTextBlock : TextBlock 
{ 
    public static readonly DependencyProperty myPropertyProperty= DependencyProperty.Register(
     "myProperty", typeof(MyProperty), typeof(MyTextBlock)); 
    public MyProperty myProperty 
    { 
     get 
     { 
      return (MyProperty)this.GetValue(myPropertyProperty); 
     } 
     set 
     { 
      this.SetValue(myPropertyProperty, value); 
     } 
    } 
} 

现在在XAML文件中定义样式,并把阶级MyTextBlock的2个对象在我的主窗口格:

<Window x:Class="WpfApplication1.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:local="clr-namespace:WpfApplication1" 
    xmlns:custom="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <ResourceDictionary> 
     <Style TargetType="{x:Type custom:MyTextBlock}"> 
      <Setter Property="Background" Value="Aqua" /> 
      <Setter Property="myProperty"> 
       <Setter.Value> 
        <custom:MyProperty exampleValue="true" /> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </ResourceDictionary> 
</Window.Resources> 
<Grid RenderTransformOrigin="0.514,0.47" Margin="100,0,0,0"> 
    <custom:MyTextBlock x:Name="textBlock1" Height="80" Width="80" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,104,62.8,0" /> 
    <custom:MyTextBlock x:Name="textBlock2" Height="80" Width="80" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,200,62.8,0" /> 
</Grid> 
</Window> 

而现在的问题,当我使用改变exampleValue假:

textBlock1.myProperty.exampleValue = false; 

exampleValue也更改为textBlock2。

正如我所见,textBlock1.myProperty和textBlock2.myProperty都返回相同的hashCode。 也许这是因为我们首先创建了myProperty的一个对象,然后Setter只是将它分配给每个MyTextBlock对象(复制)。 有没有什么办法在这里使用克隆?那么每个对象都会有他自己的“myProperty”?

我知道,这个一会正常工作,如果我定义我的财产的每个对象(但它看起来像解决办法,而不是解决方案):

<custom:MyTextBlock x:Name="textBlock1" Height="80" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,104,62.8,0"> 
    <custom:MyTextBlock.myProperty> 
     <custom:MyProperty exampleValue="False"/> 
    </custom:MyTextBlock.myProperty> 
</custom:MyTextBlock> 
<custom:MyTextBlock x:Name="textBlock2" Height="80" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,200,62.8,0"> 
    <custom:MyTextBlock.myProperty> 
     <custom:MyProperty exampleValue="False"/> 
    </custom:MyTextBlock.myProperty> 
</custom:MyTextBlock> 
+0

你的风格定义在哪里?你有没有设置x:Shared? – Brannon

+0

太棒了!有用。 我错过了我的风格x:Shared =“False”。 – Rafal

+0

非共享的缺点:您正在创建大量重复样式和对象,这可能是也可能不是您想要的。你可以让'MyProperty'成为'Freezable',然后当你要改变代码中的值时,你将*创建一个新的属性实例。 – grek40

它的“myProperty的”同一个实例,因为你创建它作为资源。 默认情况下资源共享/静态。 也许设置“X:共享”为假,可能会帮助:

<ResourceDictionary> 
    <Style TargetType="{x:Type custom:MyTextBlock}" x:Shared="false"> 
     <Setter Property="Background" Value="Aqua" /> 
     <Setter Property="myProperty"> 
      <Setter.Value> 
       <custom:MyProperty exampleValue="true" /> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

反正我不知道这是否会做的伎俩,因为它是默认的,你MyTextBlock控制的无钥匙风格,它可能是无论如何缓存。

如果它对每个MyTextBlock控件都有一个MyProperty实例,但仍然对“exampleValue”具有相同的值。

编辑:对不起,没有看到@Brannon的评论;)