gpt4 book ai didi

WPF Animate 双属性更改

转载 作者:行者123 更新时间:2023-12-02 21:26:57 26 4
gpt4 key购买 nike

我正在尝试找到一种通用方法来在每次更新 double 类型的属性时运行动画。

这必须是适用于所有 double 值的单一解决方案。这意味着我不想为每个 UIElement 属性编写专有的 AttachedProperty (一个用于 Opacity,然后另一个用于 高度)。

我想要完成的任务的伪示例:

<TextBlock x:Name="pageTitle" Text="title example" attached:AnimatedPropertyPath="(UIElement.Opacity)" Opacity="{Binding Path=TitleOpacity}" />

附加属性应该监听不透明度的任何变化,取消它并运行一个使其逐渐变化的动画。

我的问题:

  1. 这个确切的语法有意义吗?可行吗?
  2. 有没有办法通过绑定(bind)取消不透明度属性的立即更改并运行动画?
  3. 任何示例链接都将不胜感激,因为我自己找不到任何示例。

我想避免使用 DataTriggers,因为它需要太多的 xaml。最好将其作为附加属性嵌入,就像上面的伪 xaml 一样。

最佳答案

My question:

  • Does this exact syntax make sense? is it doable?

它必须是附属属性(property)吗?您愿意使用行为吗?

  • Is there a way to cancel the Opacity property immediate change by the binding and run the animation instead?

也许有一些技巧(据我所知没有)。再说一遍,这是否绝对必须拦截并取消正常的 DP 操作?

  • Any links to examples would be highly appreciated as I couldn't find any myself.

如果你可以稍微调整你的要求,我可以给你一个例子:

因此,如果您的要求是在任何 double DP 绑定(bind)的值发生变化时为其设置动画,我们可以使用 Behavior

public class AnimateBehavior : Behavior<UIElement> {
public static readonly DependencyProperty ToAnimateProperty =
DependencyProperty.Register("ToAnimate", typeof(DependencyProperty),
typeof(AnimateBehavior), new FrameworkPropertyMetadata(null));

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double),
typeof(AnimateBehavior),
new FrameworkPropertyMetadata(0.0d, FrameworkPropertyMetadataOptions.None, ValueChangedCallback));

public DependencyProperty ToAnimate {
get { return (DependencyProperty) GetValue(ToAnimateProperty); }
set { SetValue(ToAnimateProperty, value); }
}

public double Value {
get { return (double) GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}

private static void ValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var item = d as AnimateBehavior;
if (item == null || item.AssociatedObject == null) {
return;
}
var newAnimation = new DoubleAnimation((double) e.NewValue, new Duration(new TimeSpan(0, 0, 1)));
item.AssociatedObject.BeginAnimation(item.ToAnimate, newAnimation);
}
}

现在在 xaml 中:

<TextBlock Text="Hello">
<i:Interaction.Behaviors>
<local:AnimateBehavior ToAnimate="{x:Static TextBlock.OpacityProperty}" Value="{Binding ValueYouWantToBindToOpacity}" />
</i:Interaction.Behaviors>
</TextBlock>

现在,通过这种方法,您可以为该控件的任何具有 double 类型值的 DP 设置动画。如不透明度字体大小 ...

与您最初的要求的主要区别是我们不将 Value 绑定(bind)到元素。相反,我们将其绑定(bind)到Behavior。现在,当这种情况发生变化时,我们会在行为中检测到它,并通过行为的 AssociatedObject 属性,将动画应用到实际项目上。

我们还通过提供当值通过 DP 改变行为时动画的属性来满足您满足多个双 DP 类型的要求。

如果您想要更加通用,您可以让Behavior也接受动画的持续时间和类型,以使其更加通用。

DP 标识属性的替代:

如果您绝对想传递“不透明度”而不是 DP,请尝试如下操作:

public static readonly DependencyProperty ToAnimateProperty =
DependencyProperty.Register("ToAnimate", typeof(PropertyPath),
typeof(AnimateBehavior), new FrameworkPropertyMetadata(null));

public PropertyPath ToAnimate
{
get { return (PropertyPath)GetValue(ToAnimateProperty); }
set { SetValue(ToAnimateProperty, value); }
}

因此我们将 ToAnimate 设为 PropertyPath

以及在ValueChanged函数中

private static void ValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var item = d as AnimateBehavior;
if (item == null || item.AssociatedObject == null) {
return;
}
var sb = new Storyboard();
var newAnimation = new DoubleAnimation((double) e.NewValue, new Duration(new TimeSpan(0, 0, 1)));
Storyboard.SetTarget(newAnimation, item.AssociatedObject);
Storyboard.SetTargetProperty(newAnimation, item.ToAnimate);
sb.Children.Add(newAnimation);
sb.Begin();
}

我们创建一个Storyboard并使用PropertyPath,您可以拥有:

<TextBlock Text="Hello">
<i:Interaction.Behaviors>
<local:AnimateBehavior ToAnimate="Opacity" Value="{Binding ValueYouWantToBindToOpacity}" />
</i:Interaction.Behaviors>
</TextBlock>

与此方法相比,我仍然更喜欢 DP。

关于WPF Animate 双属性更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23516034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com