Привязка FocusVisualStyle с пользовательским DependencyProperty

Я пытаюсь изменить FocusVisualStyle производной кнопки, реализующей CornerRadius DependencyProperty. Для стиля кнопки все работает, но я не могу понять, как отправить значение CornerRadius в FocusVisualStyle.

Вот мой текущий код для 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>

Я также пробовал эту форму привязки:

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

Любая помощь будет приятно :)

EDIT: в соответствии с запросом, вот весь мой код:

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)));
    }


}

Темы\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: Учитывая, что я так и не нашел хорошего решения, вот как я его решил:

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);
        };
    }

person Sugz    schedule 22.11.2016    source источник


Ответы (1)


Почему бы не использовать привязку elementname?

Я упростил ваш код, чтобы проиллюстрировать мое предложение.

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

Просмотреть

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

Как видите, стиль применяется к метке внутри панели стека. Граница внутри шаблона получает свой угловой радиус снаружи (от границы внутри панели стека с именем border).

Если привязка имени элемента не является правильным подходом для вас, пожалуйста, опубликуйте еще немного кода, чтобы увидеть, где находится ваша кнопка и как получить доступ.

person ManDani    schedule 23.11.2016