2017-01-05 17 views
3

WPFスタイルに関連する問題があります。 DependencyPropertyを含むようにクラスを使用しましょう(またはそのように準備する)。私が使用して偽のためexampleValueを変更すると、今問題を参照型のWPFスタイルDependencyProperty

<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> 

そして:

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つのオブジェクトを置く

textBlock1.myProperty.exampleValue = false; 

textBlock2でもexampleValueが変更されています。

私が見るとおり、textBlock1.myPropertyとtextBlock2.myPropertyは同じhashCodeを返します。 これはおそらく、私たちが最初にmyPropertyのオブジェクトを1つ作成してから、Setterが各MyTextBlockオブジェクトにそのコピーを割り当てるだけだからです。 ここでクローンを使用する方法はありますか?だからすべてのオブジェクトは、自分の "myProperty"を持っていますか?

私は(それは回避策ではなく、解決策のように見える)オブジェクトごとに、私のプロパティを定義する場合は正しく動作意志この1つが、ことを知っている:

<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:共有しましたか? – Brannon

+0

素晴らしい!できます。 私はx:Shared = "False"がありませんでした。 – Rafal

+0

非共有の欠点:あなたはあなたが望むものであるかもしれないし、そうでないかもしれない多くの重複したスタイルとオブジェクトを作成するあなたの方法にあります。 'MyProperty'を' Freezable'にすると、コード内の値を変更しようとしているときに新しいプロパティインスタンスを作成することになります。 – grek40

答えて

1

あなたはそれを作成するので、それは「MYPROPERTY」の同じインスタンスですリソースとして。 リソースはデフォルトで共有/静的です。多分「X:共有」を設定 falseには、役立つかもしれない:

<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コントロールごとに1つのMyPropertyインスタンスがありますが、それでも "exampleValue"と同じ値を保持している場合よりも機能します。

EDIT:申し訳ありませんでした@Brannonのコメント;)