2017-01-05 6 views
3

Ich habe ein Problem im Zusammenhang mit WPF-Stilen. Verwenden wir die Klasse (oder bereiten Sie diese vor), um DependencyProperty zu enthalten.WPF-Stile für den Verweistyp 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); 
     } 
    } 
} 

Jetzt Stil in XAML-Datei definieren und legen 2 Objekte der Klasse MyTextBlock auf meinem Haupt-Fensterraster:

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

Und jetzt das Problem, wenn ich exampleValue für falsch ändern mit:

textBlock1.myProperty.exampleValue = false; 

exampleValue wird auch für textBlock2 geändert.

Wie ich sehe, beide textBlock1.myProperty und textBlock2.myProperty gleichen hashCode zurückzukehren. Wahrscheinlich liegt das daran, dass wir zunächst ein Objekt von myProperty erstellen und es dann Setter einfach jedem MyTextBlock-Objekt zuweisen (kopieren). Gibt es eine Möglichkeit, den Klon hier zu verwenden? Also wird jedes Objekt seine eigene "myProperty" haben?

Ich weiß, dass dies ein korrekt funktioniert, wenn ich meine Eigenschaften pro Objekt definieren (aber es sieht aus wie dieses Problem zu umgehen nicht Lösung):

<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

Wo ist Ihr Stil definiert? Hast du x: Geteilt? – Brannon

+0

Großartig! Es klappt. Mir fehlte x: Shared = "False" in meinem Stil. – Rafal

+0

Der Nachteil von nicht-geteilt: Sie sind auf dem Weg, um eine Menge von doppelten Stilen und Objekten zu erstellen, die möglicherweise oder nicht, was Sie wollten. Sie können 'MeineEigenschaft' zu 'Freezable' machen, dann werden Sie gezwungen, eine neue Eigenschaftsinstanz zu erstellen, wenn Sie den Wert im Code ändern wollen. – grek40

Antwort

1

Es ist die gleiche Instanz von „MyProperty“, weil Sie es schaffen als eine Ressource. Und Ressourcen sind standardmäßig freigegeben/statisch. Vielleicht Einstellung „x: Shared“ auf false, könnte helfen:

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

Jedenfalls bin ich nicht sicher, ob es den Trick tun wird, denn es ist der Standard, Keyless Stil Ihrer MyTextBlock Kontrolle und es könnte irgendwie zwischengespeichert werden .

Wenn es funktioniert, als Sie eine Instanz von MyProperty für jede MyTextBlock Kontrolle haben, aber immer noch mit dem gleichen Wert für „exampleValue“.

BEARBEITEN: Sorry @ Brannon s Kommentar nicht gesehen;)

Verwandte Themen