Metro XAML - TemplateBinding和SolidColorBrush的问题

时间:2012-05-30 20:01:58

标签: xaml windows-8 windows-runtime microsoft-metro winrt-xaml

这是一个简单的自定义控件来说明我的问题

public sealed class TestControl : Control
{
    public static DependencyProperty TestColorProperty = DependencyProperty.Register("TestColor", typeof(Brush), typeof(TestControl), new PropertyMetadata(new SolidColorBrush(Colors.Blue)));

    public Brush TestColor
    {
        get { return (Brush)GetValue(TestColorProperty); }
        set { SetValue(TestColorProperty, value); }
    }

    public TestControl()
    {
        this.DefaultStyleKey = typeof(TestControl);
    }
}

如您所见,它有一个Brush依赖项属性,默认值为Blue(在PropertyMetaData中设置,如上所示。

以下是Generic.xaml

中我控制的XAML
<Style TargetType="local:TestControl">
        <Setter Property="TestColor" Value="Red" />
        <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:TestControl">
                <Border
                    Background="{TemplateBinding TestColor}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                        <TextBlock Text="TEST"  />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如您所见,我在TestColor setter中将Style Brush依赖项属性设置为Red - 覆盖我在PropertyMetaData中声明的默认值Blue。 请注意,我的模板中的边框使用TemplateBinding来设置画笔的背景,如上所述。

那么你认为边框背景设置的颜色是什么?红色还是蓝色?

答案都不是。

如果我在我的控件中设置一个断点,此值应该可用(例如OnApplyTemplate),那么值为null,而不是预期的Red(默认值)。实际上,我在控件的所有生命周期点都设置了断点,并且从不使用ProprtyMetaData中的默认值。

在样式中设置值也没有任何作用(根据我的样式设置器delaration,它没有设置为Blue。这表明样式设置器以某种方式失败了SolidColorBrush

然而,这有效

public BlankPage()
{
    this.InitializeComponent();
    testcont.TestColor = new SolidColorBrush(Colors.Orange);
}

这也有效:

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
    <local:TestControl  TestColor="Green" />
</Grid>

但是TemplateBinding只是不起作用,这很重要,因为我试图编写可重复使用的自定义控件。

这是一个错误吗?

迪安

5 个答案:

答案 0 :(得分:0)

就个人而言,我认为这是xaml解析器中的某个错误。尝试这样的事情,它应该有效:

    <Setter Property="SelectedDayBrush">
        <Setter.Value>
            <SolidColorBrush>#7F7F7F7F</SolidColorBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="SelectedDayBrush">
        <Setter.Value>
            <SolidColorBrush Color="Orange"/>
        </Setter.Value>
    </Setter>

答案 1 :(得分:0)

这是我们要解决的问题。同时,将其设置为:

<SolidColorBrush x:Key="DefaultTestColorBrush">Red</SolidColorBrush>

然后在你的模板中:

<Setter Property="TestColor" Value="{StaticResource DefaultTestColorBrush}" />

那么你现在应该能够清除这个障碍。

答案 2 :(得分:0)

似乎还没有解决。如果你开发像自定义按钮和PointerOver效果只是更轻的背景,一个有效的技巧是在内容的顶部有白色背景的隐形PointerOverVisual。然后PointerOver动画将使其略微可见。这就是我使用的:

<VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames   Storyboard.TargetProperty="Opacity" Storyboard.TargetName="pointerOverVisual">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0.15"/>
                                    </ObjectAnimationUsingKeyFrames>

.......

<Border x:Name="Border" BorderThickness="0" Background="{TemplateBinding Background}" Margin="3">   
        content here                                                    
</Border>
    <Rectangle x:Name="pointerOverVisual" Fill="White" Opacity="0" Margin="3"/>
    <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
    <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>

答案 3 :(得分:0)

我有一个使用自定义控件的工作解决方案,而后者又多次放入用户控件中(这在我的框架中可以重复使用)。

(在generic.xaml中,回想起我创建了一个自定义控件)

<Style TargetType="local:myPad">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:myPad">
                <Path Data="..." Height="60" Width="30" Fill="{TemplateBinding myPadColor}"/>

(在myPad.cs中)

    public sealed class myPad : Control
    {
        public myPad()
        {
            this.DefaultStyleKey = typeof(myPad);
        }

        public SolidColorBrush myPadColor
        {
            get { return (SolidColorBrush)GetValue(PadColorProperty); }
            set { SetValue(PadColorProperty, value); }
        }

        public static readonly DependencyProperty PadColorProperty =
            DependencyProperty.Register("myPadColor", typeof(SolidColorBrush), typeof(myPad), new PropertyMetadata(null));
}

在我的用户控件中,然后我删除了模板控件,并且可以有多个相同的“颜色”版本......

<UserControl
    x:Class=....
    <Canvas Width="235" Height="235">
        <local:myPad x:Name="thisPad" myPadColor="White">

...

我删除了大部分多余的东西(...),但我认为你在这里得到了这个想法。我现在也相信,你可以在用户控件或代码隐藏中使用myPadColor的另一个绑定来获得创意。

不过,我正在使用带有SP3的VS2012 ..所以现在可能已经修好了。

另外,我对XAML编程很陌生,但在Tim Heuer的博客中,我找到了做依赖属性的正确方法(感谢Tim!)

如果用您的(新的SolidColorBrush(Colors.Black))替换propertymetadata值中的(null)值,您将在设计模式中获得默认值。

:)

希望有所帮助。

答案 4 :(得分:0)

您可以尝试以下代码段来绑定TestColor,

 Background="{Binding  RelativeSource={RelativeSource TemplatedParent}, Path=TestColor}"

我希望它会有所帮助。

此致 雷克斯