绑定故事板动画值

发布于 2024-09-08 08:44:34 字数 4500 浏览 5 评论 0原文

我在视图模型上有一个枚举,它代表 5 种颜色之一,并且我正在使用 ValueConverter 将这些值转换为实际颜色。

具体来说,当每个列表框项目悬停在其上时,其背景颜色会发生变化。

我有一个带有视觉状态管理器和鼠标悬停组的自定义控件,该控件使用 SplineColorKeyFrame 来设置悬停颜色的动画(这是在控件模板的 xaml 中设置的)。自定义控件仅具有悬停颜色的依赖属性。

如果 SplineColorKeyFrame 的值来自资源,或者在 xaml 中设置为固定颜色,则此方法非常有效。然而,当我将值设置为“{TemplateBinding HoverColor}”时,它只是动画为透明即使将

xaml中的DependencyProperty设置为颜色,并尝试使用控件中的TemplateBinding来读取颜色也会导致问题,动画也不会'如果我告诉它从绑定或模板绑定中获取它,则不要使用正确的颜色。

我已经窥探了该应用程序,可以看到依赖属性具有正确的值,但它似乎没有在动画中获取该值。

谁能建议如何解决这个问题?

这是我的控件模板:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}" x:Name="border">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="MouseOverGroup">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0:0:0.2"/>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                                        <SplineColorKeyFrame KeyTime="0" Value="{TemplateBinding HoverColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Normal"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <VisualStateManager.CustomVisualStateManager>
                        <ic:ExtendedVisualStateManager/>
                    </VisualStateManager.CustomVisualStateManager>

                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseEnter">
                            <ic:GoToStateAction x:Name="MouseOverAction" StateName="MouseOver"/>
                        </i:EventTrigger>
                        <i:EventTrigger EventName="MouseLeave">
                            <ic:GoToStateAction x:Name="NormalAction" StateName="Normal"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是我的自定义控件代码:

   public class MyCustomControl : Control
    {
        public static DependencyProperty HoverColorProperty = DependencyProperty.Register("HoverColor", typeof (Color),
                                                                                          typeof (MyCustomControl));
        public Color HoverColor
        {
            get
            {
                return (Color)GetValue(HoverColorProperty);
            }
            set
            {
                SetValue(HoverColorProperty, value);
            }
        }

        static MyCustomControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
        }
    }

这是主窗口 xaml:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:Test="clr-namespace:Test" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <Test:ViewModel/>
    </Window.DataContext>
    <Grid>
        <Test:MyCustomControl HoverColor="Yellow"
                              HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="150"
                              Background="Bisque">

        </Test:MyCustomControl>
    </Grid>
</Window>

I have an enum on a viewmodel which represents one of 5 colors, and I am using a ValueConverter to convert these values into actual colors.

Specifically it's for the color of each listbox item's background to change to as it is hovered over.

I have a custom control with a visual state manager and a mouseover group which uses a SplineColorKeyFrame to animate the hover color (This is set in the xaml of control template). The custom control just has a dependency property on it for the hover color.

This works great if the Value of the SplineColorKeyFrame is from a resource, or set in the xaml as a fixed color. However it just animates to transparent when I set the Value to "{TemplateBinding HoverColor}"

Even setting the DependencyProperty in the xaml to a color, and trying to use the TemplateBinding in the control to read the color causes the problem, the animation won't use the right color if I tell it to get it from a binding or template binding.

I've snooped the app and can see that the dependency property has the correct value, but it doesn't seem to be picking up that value in the animation.

Can anyone suggest how to get around this?

Here's my control template:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}" x:Name="border">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="MouseOverGroup">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0:0:0.2"/>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                                        <SplineColorKeyFrame KeyTime="0" Value="{TemplateBinding HoverColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Normal"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <VisualStateManager.CustomVisualStateManager>
                        <ic:ExtendedVisualStateManager/>
                    </VisualStateManager.CustomVisualStateManager>

                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseEnter">
                            <ic:GoToStateAction x:Name="MouseOverAction" StateName="MouseOver"/>
                        </i:EventTrigger>
                        <i:EventTrigger EventName="MouseLeave">
                            <ic:GoToStateAction x:Name="NormalAction" StateName="Normal"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Here's my custom control code:

   public class MyCustomControl : Control
    {
        public static DependencyProperty HoverColorProperty = DependencyProperty.Register("HoverColor", typeof (Color),
                                                                                          typeof (MyCustomControl));
        public Color HoverColor
        {
            get
            {
                return (Color)GetValue(HoverColorProperty);
            }
            set
            {
                SetValue(HoverColorProperty, value);
            }
        }

        static MyCustomControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
        }
    }

Here's the main window xaml:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:Test="clr-namespace:Test" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <Test:ViewModel/>
    </Window.DataContext>
    <Grid>
        <Test:MyCustomControl HoverColor="Yellow"
                              HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="150"
                              Background="Bisque">

        </Test:MyCustomControl>
    </Grid>
</Window>

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

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

发布评论

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

评论(1

死开点丶别碍眼 2024-09-15 08:44:34

我找到了这个问题的答案。事实证明,由于某种原因,如果 StoryBoard 内联在 Xaml 中,则绑定不起作用。如果将 Storyboard 放入资源中并引用 VisualStateManager 中的资源,则一切正常。

I found the answer to this problem. It turns out that, for some reason, the binding doesn't work if the StoryBoard is inline in the Xaml. If you put the Storyboard in a resource and refer to the resource in the VisualStateManager, then everything works.

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