2016-11-22 3 views
0

J'essaie de changer le FocusVisualStyle d'un bouton dérivé qui implémente un DependencyProperty CornerRadius. Tout fonctionne pour le style de bouton, mais je n'arrive pas à comprendre comment envoyer la valeur CornerRadius au FocusVisualStyle.Liaison FocusVisualStyle avec DependencyProperty personnalisée

Voici mon code actuel pour le FocusVisualStyle:

<Style x:Key="FocusVisualStyle"> 
    <Setter Property="Control.Template"> 
     <Setter.Value> 
      <ControlTemplate> 
       <Border BorderBrush="{StaticResource MyFocusBorderBrush}" 
         BorderThickness="1" 
         CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyButton}}}" 
         SnapsToDevicePixels="True" 
         UseLayoutRounding="True"/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

J'ai aussi essayer cette forme de reliure:

CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}}" 

Toute aide serait bien :)

EDIT: Comme demandé, ici serait tout mon code:

MyButton.cs:

public class MyButton : Button 
{ 
    public int CornerRadius 
    { 
     get { return (int)GetValue(CornerRadiusProperty); } 
     set { SetValue(CornerRadiusProperty, value); } 
    } 

    // DependencyProperty as the backing store for CornerRadius 
    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
     "CornerRadius", 
     typeof(int), 
     typeof(MyButton), 
     new PropertyMetadata(3) 
    ); 


    static MyButton() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton))); 
    } 


} 

Thèmes \ generic.xaml:

<Style x:Key="FocusVisualStyle"> 
    <Setter Property="Control.Template"> 
     <Setter.Value> 
      <ControlTemplate> 
       <Border BorderBrush="Red" 
         BorderThickness="1" 
         CornerRadius="{Binding CornerRadius, ElementName=background}" 
         SnapsToDevicePixels="True" 
         UseLayoutRounding="True" /> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 




<Style TargetType="{x:Type local:MyButton}"> 
    <Setter Property="Content" Value="MyButton"/> 
    <Setter Property="Background" Value="DarkGray"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="Height" Value="20"/> 
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisualStyle}"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:MyButton}"> 

       <Border x:Name="background" 
         Background="{TemplateBinding Background}" 
         BorderThickness="{TemplateBinding BorderThickness}" 
         CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}}"> 
        <ContentPresenter VerticalAlignment="Center" 
             HorizontalAlignment="Center" /> 
       </Border> 



       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" 
          Value="True"> 
         <Setter TargetName="background" 
           Property="Background" 
           Value="Gray" /> 
        </Trigger> 

        <Trigger Property="IsPressed" 
          Value="True"> 
         <Setter TargetName="background" 
           Property="Background" 
           Value="Black" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

EDIT: Considérant que je ne trouve une solution agréable, voici comment je l'ai résolu:

public MyButton() 
    { 
     Loaded += (s, e) => 
     { 
      string styleStr = "<Style xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" + 
      "<Setter Property = \"Control.Template\"> " + 
       "<Setter.Value> " + 
        "<ControlTemplate> " + 
         "<Rectangle Margin = \"-2\" " + 
            "Stroke = \"" + Resource<SolidColorBrush>.GetColor("MaxFocusBorder") + "\" " + 
            "StrokeThickness = \"1\" " + 
            "StrokeDashArray = \"1 2\" " + 
            "RadiusX = \"" + CornerRadius + "\" " + 
            "RadiusY = \"" + CornerRadius + "\" " + 
            "SnapsToDevicePixels = \"True\" " + 
            "UseLayoutRounding = \"True\" /> " + 
        "</ControlTemplate> " + 
       " </Setter.Value> " + 
      "</Setter> " + 
     "</Style>"; 

      FocusVisualStyle = (Style)XamlReader.Parse(styleStr); 
     }; 
    } 

Répondre

0

Pourquoi ne pas utiliser un elementname-binding?

J'ai simplifié votre code pour donner une illustration de ma suggestion.

<Style x:Key="FocusVisualStyle"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border BorderBrush="Red" BorderThickness="1" CornerRadius="{Binding ElementName=border, Path=CornerRadius}"> 
         <Label Foreground="{Binding ElementName=rectangle, Path=Fill}">Template</Label> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Voir

<StackPanel> 
    <Label Style="{StaticResource FocusVisualStyle}" Height="30"/> 
    <Rectangle x:Name="rectangle" Height="30" Fill="Green"/> 
    <Border x:Name="border" CornerRadius="15"/> 
</StackPanel> 

Comme vous pouvez le voir le style est appliqué sur l'étiquette à l'intérieur du StackPanel. La bordure à l'intérieur du gabarit obtient son angle de l'extérieur (à partir de la bordure à l'intérieur de la pile, nommée border).

Si la liaison par nom d'élément n'est pas la bonne approche pour vous, envoyez un peu plus de code pour voir où se trouve votre bouton et comment y accéder.