在 VisualState Storyboard 中使用绑定

发布于 2024-10-05 10:00:44 字数 3919 浏览 1 评论 0原文

我正在为 WPF 应用程序编写自定义控件。我想在 VisualState 定义的 Storyboard 中使用彩色动画。该动画的 To 属性应绑定到我的控制对象的依赖属性。这似乎不起作用。

我在 Silverlight 论坛中找到了一个描述完全相同问题的帖子,其中声称这在 SL4 RTM 中有效:http://forums.silverlight.net/forums/p/174655/423324.aspx。 但是,当我尝试使用 VS2010 WPF 应用程序中发布的代码时,它不起作用,这意味着颜色不会改变。我能够在 VisualState Storyboard 中执行的唯一绑定是到 StaticResource

有什么想法吗?

编辑:

添加代码片段:

来自 Generic.xaml:

<Style TargetType="{x:Type local:TestCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TestCustomControl}">
                <Border BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Name="MyBorder">
                    <Border.Background>
                        <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ColdColor}" />
                    </Border.Background>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <!-- This works: -->
                                    <!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="Red"  Duration="0:0:0.2"/>-->

                                    <!-- This also works: --> 
                                    <!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{StaticResource HotColorRes}"  Duration="0:0:0.2"/>-->

                                    <!-- This doesn't work: -->
                                    <ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=HotColor}"  Duration="0:0:0.2"/>

                                </Storyboard>
                            </VisualState>

                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

TestCustomControl.cs:

public class TestCustomControl : Button
{
    static TestCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl)));
    }

    public Color HotColor
    {
        get { return (Color)GetValue(HotColorProperty); }
        set { SetValue(HotColorProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HotColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HotColorProperty =
        DependencyProperty.Register("HotColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(Colors.Aqua));

    public Color ColdColor
    {
        get { return (Color)GetValue(ColdColorProperty); }
        set { SetValue(ColdColorProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ColdColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ColdColorProperty =
        DependencyProperty.Register("ColdColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(Colors.Aqua));
}

I am writing a custom control for a WPF application. I want to use a color animation in a Storyboard in a VisualState definition. The To property of that animation should be bound to a dependency property of my control object. This does not appear to work.

I have found a thread in a Silverlight forum describing the exact same problem, in which it is claimed that this works in SL4 RTM: http://forums.silverlight.net/forums/p/174655/423324.aspx.
However, when I try using the code posted in my VS2010 WPF application then it does not work, meaning that the color does not change. The only binding I have been able to do within a VisualState Storyboard is to StaticResource.

Any ideas?

EDIT:

Added code snippets:

from Generic.xaml:

<Style TargetType="{x:Type local:TestCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TestCustomControl}">
                <Border BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Name="MyBorder">
                    <Border.Background>
                        <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ColdColor}" />
                    </Border.Background>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <!-- This works: -->
                                    <!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="Red"  Duration="0:0:0.2"/>-->

                                    <!-- This also works: --> 
                                    <!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{StaticResource HotColorRes}"  Duration="0:0:0.2"/>-->

                                    <!-- This doesn't work: -->
                                    <ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=HotColor}"  Duration="0:0:0.2"/>

                                </Storyboard>
                            </VisualState>

                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

TestCustomControl.cs:

public class TestCustomControl : Button
{
    static TestCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl)));
    }

    public Color HotColor
    {
        get { return (Color)GetValue(HotColorProperty); }
        set { SetValue(HotColorProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HotColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HotColorProperty =
        DependencyProperty.Register("HotColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(Colors.Aqua));

    public Color ColdColor
    {
        get { return (Color)GetValue(ColdColorProperty); }
        set { SetValue(ColdColorProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ColdColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ColdColorProperty =
        DependencyProperty.Register("ColdColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(Colors.Aqua));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

£烟消云散 2024-10-12 10:00:44

如果您在 Generic.xaml 中为 指定 x:Name 属性,它将按预期工作,如下所示:

<!-- This WILL work: -->
<ColorAnimation x:Name="PART_ColorAnimation"
                Storyboard.TargetProperty="Background.Color"
                Storyboard.TargetName="MyBorder"
                Duration="0:0:0.2" />

并为 < code>To 属性稍后在代码后面及时通过覆盖 OnApplyTemplate()

public override void OnApplyTemplate()
{
    var colorAnimation = (ColorAnimation)Template.FindName("PART_ColorAnimation", this);

    if(colorAnimation == null)
        return;

    var binding = new Binding("HotColor") { Source = this };
    BindingOperations.SetBinding(colorAnimation,
                                 ColorAnimation.ToProperty,
                                 binding);
}

希望有所帮助。

It will work as expected if you specify x:Name attribute for <ColorAnimation> in Generic.xaml like this:

<!-- This WILL work: -->
<ColorAnimation x:Name="PART_ColorAnimation"
                Storyboard.TargetProperty="Background.Color"
                Storyboard.TargetName="MyBorder"
                Duration="0:0:0.2" />

and set binding for To property later in code behind in time when the template will be already applied to control by overriding OnApplyTemplate() in TestCustomControl.cs:

public override void OnApplyTemplate()
{
    var colorAnimation = (ColorAnimation)Template.FindName("PART_ColorAnimation", this);

    if(colorAnimation == null)
        return;

    var binding = new Binding("HotColor") { Source = this };
    BindingOperations.SetBinding(colorAnimation,
                                 ColorAnimation.ToProperty,
                                 binding);
}

Hope that help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文