Нужно ли создавать пользовательский элемент управления? - PullRequest
3 голосов
/ 12 августа 2011

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

То, что я хочу, - это фактическое свойство CornerRadius, которое я могу установить для каждой кнопки, и мне не нужно создавать другой стиль каждый раз, когда я хочу другой радиус угла.

Является ли мое единственное решение здесь для создания пользовательского элемента управления?

1 Ответ

3 голосов
/ 12 августа 2011

После некоторой игры я пришел к выводу, что самый простой способ сделать это - привязать к присоединенному свойству типа ConerRadius.

В шаблоне вы привязываете угловой радиус следующим образом:

<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 (Expression Blend просто позволяет вам делать это в графическом интерфейсе, что приятно, но вы можете сделать это вручную)
  • Вы можете создать прикрепленное поведениеодно свойство Radius, которое устанавливает все 4 угла.
  • Создайте вложенное свойство зависимостей (свяжите шаблон с новым свойством Radius)
  • Вы можете создать пользовательский элемент управления, как вы предлагаете.
...