2017-01-03 15 views
2

要約:私はカスタムコントロールを書くたびに依存関係プロパティHighlightBrushを実装して自分自身を繰り返すことはしません。完全を期すために私のカスタムコントロールライブラリの依存プロパティの継承を超える継承

public class MyButton : Button 
{ 
    public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(MyButton), new PropertyMetadata(default(Brush))); 

    public Brush HighlightBrush 
    { 
     get { return (Brush) GetValue(HighlightBrushProperty); } 
     set { SetValue(HighlightBrushProperty, value); } 
    } 
} 
public class MyTextBox : TextBox 
{ 
    public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(MyTextBox), new PropertyMetadata(default(Brush))); 

    public Brush HighlightBrush 
    { 
     get { return (Brush)GetValue(HighlightBrushProperty); } 
     set { SetValue(HighlightBrushProperty, value); } 
    } 
} 

Generic.xaml内部HighlightBrushの使い方::

<Style TargetType="{x:Type custom:MyButton}"> 
    <Setter Property="Cursor" Value="Hand" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type custom:MyButton}"> 
       <Border x:Name="Border" Background="{TemplateBinding Background}"> 
        <ContentPresenter /> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter TargetName="Border" Property="Background" Value="{Binding HighlightBrush, RelativeSource={RelativeSource TemplatedParent}}" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<Style TargetType="{x:Type custom:MyTextBox}"> 
    <Setter Property="BorderThickness" Value="1" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type custom:MyTextBox}"> 
       <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> 
        <ScrollViewer x:Name="PART_ContentHost" /> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsFocused" Value="True"> 
         <Setter Property="BorderBrush" Value="{Binding HighlightBrush, RelativeSource={RelativeSource TemplatedParent}}" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

質問:私は、上のコードの重複を避けることができますどのように

は、ここで厄介なコードの重複の2例であり、依存関係のプロパティ?複数の継承がないので、別の基本クラスを導入することはできません。依存関係のプロパティには具体的な型を作成する必要があるため、コンポジションを使用できません。たぶん添付された依存関係プロパティは、コントロールクラスとXAMLの中でそれらとやりとりするのに役立ちますか?

(私はTextBlock.TextTextBox.Textは私の問題に非常によく似ていると思います。)

答えて

2

あなたはAttachedPropertiesを使用して、XAMLでそれらと対話することができ、それはもう少し作業を必要とし、あなたは構文で慣れます。

は、例えば、私はGeometria(ジオメトリ)性質を持つように、任意のコントロールの種類を望んでいたので、私はそれを含むようにAttachedPropertyクラスを作成した(ポルトガル語での名前):

public static class PropriedadeAnexada 
{ 
    public static readonly DependencyProperty GeometriaProperty 
     = DependencyProperty.RegisterAttached(
      "Geometria", 
      typeof(Geometry), 
      typeof(PropriedadeAnexada), 
      new FrameworkPropertyMetadata(
       default(Geometry), 
       FrameworkPropertyMetadataOptions.AffectsRender 
       | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault 
      ) 
     ); 

    public static Geometry GetGeometria (DependencyObject element) 
    { 
     return (Geometry)element.GetValue(GeometriaProperty); 
    } 

    public static void SetGeometria (DependencyObject element, Geometry value) 
    { 
     element.SetValue(GeometriaProperty, value); 
    } 
} 

次に、XAMLで、私はセットここで私はそれを設定することで、私のコントロールでは、このプロパティを使用できるよう、そして今度は、このようなTemplateを使用して自分のスタイルでそれにアクセス

 <Button 
      controls:PropriedadeAnexada.Geometria="{StaticResource ÍconeNovoExame}"    
      Style="{StaticResource BotãoGeometria}" 
     /> 

注:

このように、このプロパティ
<ControlTemplate 
    x:Key="ControleGeometriaTemplate" 
    TargetType="{x:Type Control}" 
> 
    <Grid x:Name="root"> 
      <Path 
       x:Name="ícone" 
       Data="{Binding Path=(local:PropriedadeAnexada.Geometria), RelativeSource={RelativeSource TemplatedParent}}" 
      /> 
    </Grid> 
</ControlTemplate> 
+0

私のニーズを満たすために、私はまだ 'public {Geometry HighlightBrush {get ProprietaryAnexada.GetGeometria(this);}を追加する必要があります。 } {PropriedadeAnexada.SetGeometria(this、value);}を設定します。 }} '!しかし、むしろ 'local:PropriedadeAnexada.'という接頭辞でバインドする必要はありません。それは容認できる解決策です! – Marcel

+0

さて、継承を介して同じインプリメンテーションを複数のクラスに再利用したい場合は、そのクラスのDependencyProperty(DependencyProperty)をいくつかのクラスに配置する必要があります。プレースホルダ。また、プロパティがターゲットクラス定義にないため、XAMLでそのプロパティを追加の構文で参照する必要があります。私は他の方法を知らない。 – heltonbiker

+1

残念ながら、このパターンは私に多くの問題をもたらしました:http://stackoverflow.com/questions/41674886/visual-studio-2015-design-view-crashes-xdesproc-exe-on-nullreferenceexception。個人的に、私は控える。しかし、それはあなたのせいではありません!ソリューションがうまくいくと私は確信しています...だから、ここに解決策のマークがあります。最後に;-) – Marcel