переопределить свойство шаблона элемента управления в XAML

Если у меня есть следующий XAML, определенный в generic.xaml

<Style TargetType="{x:Type TextBox}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="CaretBrush" Value="{StaticResource TextBoxCaretBrush}" />
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="MinWidth" Value="120" />
    <Setter Property="MinHeight" Value="20" />
    <Setter Property="AllowDrop" Value="True" />
    <Setter Property="Foreground" Value="{StaticResource TextBoxTextBrush}" />
    <Setter Property="Padding" Value="5,3,0,5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border x:Name="Border" CornerRadius="5" Padding="2" BorderThickness="1">
                    <Border.Background>
                        <SolidColorBrush Color="{StaticResource TextBoxBackgroundColor}" />
                    </Border.Background>
                    <Border.BorderBrush>
                        <SolidColorBrush Color="{StaticResource TextBoxBorderColor}" />
                    </Border.BorderBrush>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlLightColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="ReadOnly">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledControlDarkColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="BorderBrush" TargetName="Border" Value="{StaticResource TextBoxBorderSelectedBrush}" />
                        <Setter Property="Effect">
                            <Setter.Value>
                                <DropShadowEffect ShadowDepth="0" Color="{StaticResource HighlightColor}" Opacity="1" BlurRadius="5" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="BorderThickness" Value="2" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И, на мой взгляд, я определил следующий XAML для отображения TextBox с использованием вышеуказанного стиля.

<TextBox Name="UserName" attachedProperties:KeyboardNavigationExt.TabOnEnter="True" Grid.Row="1" KeyboardNavigation.TabIndex="1" Grid.Column="2" Grid.ColumnSpan="3" cal:Message.Attach="[Event TextChanged] = [Action CanLogin]" />

Это отображает TextBox в представлении с CornerRadius из 5 на Border в Template.

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

<TextBox Name="UserName" CornerRadius="5,5,0,0" attachedProperties:KeyboardNavigationExt.TabOnEnter="True" Grid.Row="1" KeyboardNavigation.TabIndex="1" Grid.Column="2" Grid.ColumnSpan="3" cal:Message.Attach="[Event TextChanged] = [Action CanLogin]" />

Но TextBox не имеет CornerRadius, как я могу добиться этого, чтобы я мог изменить CornerRadius из Border в представлении XAML


person Neil Stevens    schedule 07.09.2015    source источник
comment
Создайте еще одно прикрепленное свойство (прокси), как вы сделали с KeyboardNavigationExt.TabOnEnter, но это свойство типа CornerRadius, установите значение по умолчанию в Style и в шаблоне привяжите ConrnerRadius к этому присоединенному свойству TemplatedParent. Таким образом, вы сможете изменить значение на TextBox. Проверьте этот ответ   -  person dkozl    schedule 07.09.2015
comment
Как мне связать это в шаблоне? я пробовал CornerRadius="{TemplateBinding CornerRadius}" но получаю ошибку   -  person Neil Stevens    schedule 07.09.2015
comment
Проверьте ссылку на ответ в предыдущем комментарии. Вы используете привязку RelativeSource к TemplatedParent   -  person dkozl    schedule 07.09.2015
comment
Спасибо, это то, чего мне не хватало, я полностью пропустил ссылку в вашем комментарии выше, если вы добавите свой ответ, я могу отметить как ответ   -  person Neil Stevens    schedule 07.09.2015


Ответы (1)


Как упоминалось в комментарии, вам нужно свойство прокси, которое вы можете установить для TextBox и привязать в шаблоне. Итак, создайте AttachedProprty типа CornerRadius

public static class AttachedProperties
{
    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(AttachedProperties), new UIPropertyMetadata());

    public static void SetCornerRadius(DependencyObject d, CornerRadius source)
    {
        d.SetValue(CornerRadiusProperty, source);
    }

    public static CornerRadius GetCornerRadius(DependencyObject d)
    {
        return (CornerRadius)d.GetValue(CornerRadiusProperty);
    }
}

изменить ControlTemplate и привязать к этому свойству TemplatedParent

<ControlTemplate TargetType="{x:Type TextBox}">
    <Border CornerRadius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:AttachedProperties.CornerRadius)}"/>
</ControlTemplate>

добавитьSetter к вашему Style со значением по умолчанию

<Setter Property="local:AttachedProperties.CornerRadius" Value="5"/>

а затем вы можете изменить его вручную для каждого TextBox

<TextBox local:AttachedProperties.CornerRadius="5,5,0,0" .../>
person dkozl    schedule 07.09.2015