FocusVisualStyle与自定义DependencyProperty绑定

时间:2016-11-22 23:45:02

标签: c# wpf dependency-properties focusvisualstyle

我正在尝试更改实现CornerRadius DependencyProperty的派生按钮的FocusVisualStyle。一切都适用于按钮样式,但我无法弄清楚如何将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}}"

任何帮助都会很好:)

编辑:根据要求,这是我的所有代码:

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>

编辑:考虑到我从来没有找到一个好的解决方案,这就是我解决它的方法:

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

1 个答案:

答案 0 :(得分:0)

为什么不使用 elementname -binding?

我已经简化了您的代码,以便对我的建议进行说明。

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

如您所见,样式应用于stackpanel内的标签。模板中的边框从外部(从名为 border 的stackpanel内部的边框)获取它的cornerradius。

如果元素名称绑定不是正确的方法,那么你可以发布更多代码来查看按钮的位置以及如何访问。