我需要创建自定义控件吗?

时间:2011-08-12 07:58:42

标签: silverlight windows-phone-7 custom-controls

我想调整按钮上的转角半径。我可以通过创建单独的样式资源并在模板中设置边框的角半径来完成此操作。但是,我必须为每个变体创建一个单独的样式。

我想要的是一个实际的CornerRadius属性,我可以为每个按钮设置,而不是每次我想要一个不同的角半径时都不需要创建另一个样式。

这是我唯一能创建自定义控件的解决方案吗?

1 个答案:

答案 0 :(得分:3)

经过一些游戏后我得出结论最简单的方法是绑定到ConerRadius类型的附加属性。

在模板中,您可以像这样绑定Corner Radius:

<Border x:Name="Background" CornerRadius="{TemplateBinding Corner.Radii}" 

你这样使用它:

<Button Corner.Radii="10"

甚至是这样:

<Button Corner.Radii="2, 10, 10, 2"

示例:

enter image description here

完整代码如下:

附属物类:

public static class Corner
{
    public static readonly DependencyProperty RadiiProperty = DependencyProperty.RegisterAttached(
      "Radii",
      typeof(CornerRadius),
      typeof(UIElement), null);

    public static void SetRadii(UIElement element, CornerRadius value)
    {
        element.SetValue(RadiiProperty, value);
    }

    public static CornerRadius GetRadii(UIElement element)
    {
        return (CornerRadius)element.GetValue(RadiiProperty);
    }
}

使用它的示例页面:

注意:对于此示例,按钮模板包含在内。

<UserControl x:Class="CornerBehaviorTest.MainPage"
    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:CornerBehaviorTest="clr-namespace:CornerBehaviorTest" mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="AliceBlue"/>
            <Setter Property="Foreground" Value="Red"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#F2FFFFFF"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#CCFFFFFF"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#7FFFFFFF"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF6DBDD1"/>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" To="#D8FFFFFF"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#C6FFFFFF"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#8CFFFFFF"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#3FFFFFFF"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="Background" CornerRadius="{TemplateBinding CornerBehaviorTest:Corner.Radii}" Background="White" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                                <Grid Background="{TemplateBinding Background}"  Margin="1">
                                    <Border Opacity="0"  x:Name="BackgroundAnimation" Background="#FF448DCA" />
                                    <Rectangle x:Name="BackgroundGradient" >
                                        <Rectangle.Fill>
                                            <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                                                <GradientStop Color="#FFFFFFFF" Offset="0" />
                                                <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                                                <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                                                <GradientStop Color="#C6FFFFFF" Offset="1" />
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>
                            </Border>
                            <ContentPresenter
                              x:Name="contentPresenter"
                              Content="{TemplateBinding Content}"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              Margin="{TemplateBinding Padding}"/>
                            <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
                            <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
        <Grid x:Name="LayoutRoot" Background="White">
        <Button CornerBehaviorTest:Corner.Radii="10,5,5,5" Content="Button" Height="40" HorizontalAlignment="Left" Margin="130,22,0,0" Name="button1" VerticalAlignment="Top" Width="73" />
    </Grid>
</UserControl>

旧答案

您有几种选择:

  • 使用应用程序资源创建所需的各种半径类型并使用StaticResource Binding(Expression Blend只允许您在GUI中执行此操作,这很好,但您可以手动执行此操作)
  • 您可以创建附加行为并使用单个Radius属性设置所有4个角。
  • 创建附加的依赖项属性(将模板绑定到新的Radius属性)
  • 您可以按照建议创建自定义控件。