ControlTemplate在Blend中正常工作,但在实际应用中却没有

时间:2016-03-07 07:24:18

标签: c# wpf user-interface controls mahapps.metro

我创建了一个自定义按钮,没什么太花哨的,只是mahApps SquareButton的扩展,左侧有一个彩色标记。

enter image description here

我在Blend中设计了它,并将代码复制到我在Visual Studio中的实际应用程序中。当在Blend中启动时,它工作得很好,当在Visual Studio中启动时,标记不可见,并且文本左对齐,按钮看起来几乎像普通的SquareButton。我做错了什么?

enter image description here

我从Blend复制的XAML:

<Style x:Key="MarkerButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="MinHeight" Value="25"/>
    <Setter Property="FontFamily" Value="{DynamicResource DefaultFont}"/>
    <Setter Property="FontWeight" Value="SemiBold"/>
    <Setter Property="Background" Value="{DynamicResource WhiteBrush}"/>
    <Setter Property="BorderBrush" Value="{DynamicResource BlackBrush}"/>
    <Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
    <Setter Property="Padding" Value="5,6"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement">
                                        <SplineDoubleKeyFrame KeyTime="0" Value="0.7"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PART_ContentPresenter">
                                        <EasingDoubleKeyFrame KeyTime="0" Value="0.3"/>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused"/>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ValidationStates">
                            <VisualState x:Name="Valid"/>
                            <VisualState x:Name="InvalidFocused"/>
                            <VisualState x:Name="InvalidUnfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{x:Null}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Rectangle Fill="#FFAA2222" HorizontalAlignment="Left" Width="15" Margin="{Binding BorderThickness, ElementName=Background}" StrokeThickness="0" IsHitTestVisible="False"/>
                    <Rectangle x:Name="DisabledVisualElement" Fill="{DynamicResource ControlsDisabledBrush}" IsHitTestVisible="False" Opacity="0"/>
                    <Custom:ContentControlEx x:Name="PART_ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{DynamicResource GrayBrush8}"/>
                        <Setter Property="Foreground" Value="{DynamicResource BlackBrush}"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="{DynamicResource BlackBrush}"/>
                        <Setter Property="Foreground" Value="{DynamicResource WhiteBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

只是按钮的自定义部分:

<Rectangle Fill="#FFAA2222" HorizontalAlignment="Left" Width="15" Margin="{Binding BorderThickness, ElementName=Background}" StrokeThickness="0" IsHitTestVisible="False"/>

我把它放到VS中的代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
                xmlns:view="clr-namespace:MyApplication.View">
    <Style x:Key="MarkerButtonStyle" TargetType="{x:Type view:MarkerButton}">
    ...
    </Style>
    <Style TargetType="{x:Type view:MarkerButton}" BasedOn="{StaticResource MarkerButtonStyle}"/>
</ResourceDictionary>

然后我使用了这样的按钮:

<view:MarkerButton MarkerColor="{Binding Color}" Content="{Binding Name}" MarkerWidth="15" .... />

使用Punker76扩展按钮的解决方案我得到了这个:

enter image description here

定位被打破,但xaml似乎是正确的......

修复了我的旧解决方案,问题是我的宽度:我将其声明为uint而不是double。仍然,按钮看起来与正常的方形样式(不同的边框,焦点矩形,文本对齐)不同,我不知道为什么。

enter image description here

1 个答案:

答案 0 :(得分:1)

首先你告诉我们这个

<Style x:Key="MarkerButtonStyle" TargetType="{x:Type Button}">

然后这个

<Style x:Key="MarkerButtonStyle" TargetType="{x:Type view:MarkerButton}">

如果MarkerButton是一个按钮,那么如果你使用第一个以Button为目标的样式,那么这应该有用

<Style TargetType="{x:Type view:MarkerButton}"
       BasedOn="{StaticResource MarkerButtonStyle}">
       <Setter Property="MarkerColor" Value="#FFAA2222" />
       <Setter Property="MarkerWidth" Value="15" />
</Style>

enter image description here

<Button Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" />

修改

您还可以使用附加属性和继承样式,而不是创建新的按钮类。

public static class ButtonsHelper
{
    public static readonly DependencyProperty MarkerColorProperty
        = DependencyProperty.RegisterAttached("MarkerColor", typeof(Brush), typeof(ButtonsHelper), new FrameworkPropertyMetadata(Brushes.Transparent));

    public static void SetMarkerColor(DependencyObject obj, Brush value)
    {
        obj.SetValue(MarkerColorProperty, value);
    }

    public static Brush GetMarkerColor(DependencyObject obj)
    {
        return (Brush)obj.GetValue(MarkerColorProperty);
    }

    public static readonly DependencyProperty MarkerWidthProperty
        = DependencyProperty.RegisterAttached("MarkerWidth", typeof(double), typeof(ButtonsHelper), new FrameworkPropertyMetadata(15d));

    public static void SetMarkerWidth(DependencyObject obj, double value)
    {
        obj.SetValue(MarkerWidthProperty, value);
    }

    public static double GetMarkerWidth(DependencyObject obj)
    {
        return (double)obj.GetValue(MarkerWidthProperty);
    }
}

使用

<Style x:Key="MarkerButtonStyle" BasedOn="{StaticResource SquareButtonStyle}" TargetType="{x:Type Button}">
    <Setter Property="ButtonsHelper.MarkerColor" Value="#FFAA2222"/>
    <Setter Property="ButtonsHelper.MarkerWidth" Value="15"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid HorizontalAlignment="Stretch">
                    <Rectangle Width="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=(ButtonsHelper.MarkerWidth), Mode=OneWay}"
                               HorizontalAlignment="Left"
                               Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=(ButtonsHelper.MarkerColor), Mode=OneWay}"
                               IsHitTestVisible="False"
                               StrokeThickness="0" />
                    <TextBlock HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Text="{Binding Mode=OneWay}" />
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style BasedOn="{StaticResource MarkerButtonStyle}" TargetType="{x:Type Button}" />

您现在可以像这样更改XAML中的颜色

<Button Content="Test" ButtonsHelper.MarkerColor="YellowGreen" />

enter image description here