Metro / Windows Store App:无法在ControlTemplate中将Foreground用作TemplateBinding源?

时间:2012-09-16 02:30:16

标签: microsoft-metro controltemplate foreground templatebinding coloranimation

我想使用我的控件前景的值作为ControlTemplate中VisualState ColorAnimation的源。

我的模板定义主要类似于ToggleButton的标准模板,带有一些mod(标记为<<<<>>>>):

<Style TargetType="ToggleButton>
  <Setter .../>
  ...
  <<< <Setter Property="Foreground" Value="#FF000000"/> >>>
  ...
  <Setter .../>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ToggleButton">
        <Grid>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState .../>
              <VisualState x:Name="PointerOver">
                <Storyboard>
                  <ColorAnimation Duration="0" Storyboard.Target="BackgroundGradient" Storybord.TargetProperty="(Rectangel.Fill).(GradientBrush.GradientStop)[1].(GradientStopColor)" <<< To="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" >>> />
                </Storyboard>
              </VisualState>
      ...
    ...
  ...
</Style>
...
...
<ToggleButton <<< Foreground="#FFFF0000" >>> ...../>

所以我希望看到动画使用设置的前景色(#FFFF0000)作为鼠标动画的一部分,但它什么也没做。 当我在动画定义中写To =“#FFFF0000”时,我得到了预期的结果,但是我想让动画颜色保持动态,并且在我的应用程序中为每个ToggleButton保持不同。

知道如何解决这个问题吗?

请!

编辑:尝试通过向ContentPresenter添加一个带有LinearGradientBrush的新Rectangle来实现类似的效果,其中一个GradientStop应绑定到{TemplateBinding Foreground},我现在得到一个错误,可能会启发我的问题的原因“类型为'Windows.UI.xaml.DependencyProperty'的对象无法转换为'System.Windows.DependencyProperty'类型。” 看起来{TemplateBinding ...}会产生错误输入的DependencyProperty,或者GradientStop需要Windows Store应用中的错误类型。 然而!有没有办法通过XAML中的显式类型转换或任何其他解决方法来克服这个问题?

由于

1 个答案:

答案 0 :(得分:2)

所以,我终于自己解决了。

收到错误信息后(参见原帖的“编辑”)我尝试制作一个合适的转换器,现在我可以踢自己,因为没有看到明显的!

它与WinRT或TemplateBinding无关或Windows.UI.Xaml&lt; - &gt;之间的不兼容性。和System-Windows对象。

我只是没有意识到Foreground是一个Brush类型(在我的例子中是一个SolidColorBrush),而GradientStopColor需要一个Color!

一旦我创建了BrushToColorConverter并将其与RelativeSource绑定结合使用(因为TemplateBinding不允许转换器),它就可以工作。

  XAML:
<Page.Resources>
  <local:BrushToColorConverter x:Key="Brush2Color" DefaultOpacity="1.0"/>
</Page.Resources>
...
<ColorAnimation Duration="0" 
                Storyboard.TargetName="BackgroundGradient"
                Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" 
                To="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
                     Path=Foreground, 
                     Converter={StaticResource Brush2Color}, 
                     ConverterParameter=0.5}"
/>


CodeBehind:
public class BrushToColorConverter : IValueConverter
{
  private double defaultOpacity = 1;
  public double DefaultOpacity
  {
    set { defaultOpacity = value; }
  }

  public object Convert(object value, Type targetType, object parameter, string culture)
  {
    SolidColorBrush brush = value as SolidColorBrush;
    double opacity;

    if (!Double.TryParse((string)parameter, out opacity))
      opacity = defaultOpacity;

    if (brush == null)
      return Colors.Transparent;
    else
      return Color.FromArgb((byte)(255.0 * brush.Opacity * opacity), 
                            brush.Color.R, 
                            brush.Color.G, 
                            brush.Color.B
                           );
  }

  public object ConvertBack(object value, Type targetType, object parameter, string culture)
  {
    return null;
  }
}