我想对从旧值到新值的转换进行动画处理,就像在许多软件中看到的那样,即当绑定属性的值发生变化时,我想将文本框的文本增加或减少一个特定的偏移量,直到它达到新值。举个例子:
初始值:26.0% 新值:43.5%
动画: 26.5% -> 30.0% -> 30.5% ....... -> 43.4
是否可以使用 .Net 的标准设备执行此操作,或者您是否需要自定义控件?
在此先感谢您的帮助。
我想对从旧值到新值的转换进行动画处理,就像在许多软件中看到的那样,即当绑定属性的值发生变化时,我想将文本框的文本增加或减少一个特定的偏移量,直到它达到新值。举个例子:
初始值:26.0% 新值:43.5%
动画: 26.5% -> 30.0% -> 30.5% ....... -> 43.4
是否可以使用 .Net 的标准设备执行此操作,或者您是否需要自定义控件?
在此先感谢您的帮助。
恐怕我不知道 .NET 是否有自定义控件。但是在特殊监督下,您可以非常轻松地做到这一点。
第一步:创建一个计时器
第二步:在表单加载事件中运行 timer1 对象 [timerName.Start();]
第三步:创建一个全局变量来控制第二个。局部变量
第四步:通过对 Timer 对象的滴答事件执行第二次检查来检查文本框内容
private void Form1_Load(object sender,EventArgs e) { timer1.Start(); }
private int elapsed;
private void timer1_Tick(object sender,EventArgs e)
{
elapsed = elapsed + 1;
if (elapsed == 15)
{
textBox1.Text = "%" + "next value 1";
}
if (elapsed == 30)
{
textBox1.Text = "%" + "next value 2";
}
if (elapsed == 45)
{
textBox1.Text = "%" + "next value 3";
}
}
希望能帮到你。如果我不能帮你,请写下来。好编码!
,Double 数字离散动画的辅助代理示例:
using System;
using System.Windows;
namespace Proxy
{
public partial class DeltaNumberAnimator : Freezable
{
protected override Freezable CreateInstanceCore()
{
throw new NotImplementedException();
}
}
}
using System;
using System.Windows;
namespace Proxy
{
public partial class DeltaNumberAnimator
{
/// <summary>Source of number</summary>
public double Source
{
get => (double)GetValue(SourceProperty);
set => SetValue(SourceProperty,value);
}
/// <summary><see cref="DependencyProperty"/> for property <see cref="Source"/>.</summary>
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(nameof(Source),typeof(double),typeof(DeltaNumberAnimator),new PropertyMetadata(0d,(d,e) => ((DeltaNumberAnimator)d).SourceChanged(e)));
/// <summary>Number with animated change</summary>
public double Number
{
get => (double)GetValue(NumberProperty);
private set => SetValue(NumberPropertyKey,value);
}
private static readonly DependencyPropertyKey NumberPropertyKey =
DependencyProperty.RegisterReadOnly(nameof(Number),NumberChanged));
/// <summary><see cref="DependencyProperty"/> for property <see cref="Number"/>.</summary>
public static readonly DependencyProperty NumberProperty = NumberPropertyKey.DependencyProperty;
/// <summary>Sets the delta value for a discrete change in the <see cref="Number"/> property.</summary>
public double Delta
{
get => (double)GetValue(DeltaProperty);
set => SetValue(DeltaProperty,value);
}
/// <summary><see cref="DependencyProperty"/> for property <see cref="Delta"/>.</summary>
public static readonly DependencyProperty DeltaProperty =
DependencyProperty.Register(nameof(Delta),new PropertyMetadata(0.01,DeltaChanged,CoerceDelta));
/// <summary>Number increment interval. </summary>
public TimeSpan Interval
{
get => (TimeSpan)GetValue(IntervalProperty);
set => SetValue(IntervalProperty,value);
}
/// <summary><see cref="DependencyProperty"/> for property <see cref="Interval"/>.</summary>
public static readonly DependencyProperty IntervalProperty =
DependencyProperty.Register(nameof(Interval),typeof(TimeSpan),new PropertyMetadata(TimeSpan.Zero,IntervalChanged));
/// <summary>Animation in progress.</summary>
public bool IsAnimation
{
get => (bool)GetValue(IsAnimationProperty);
private set => SetValue(IsAnimationPropertyKey,value);
}
public static readonly DependencyPropertyKey IsAnimationPropertyKey =
DependencyProperty.RegisterReadOnly(nameof(IsAnimation),typeof(bool),new PropertyMetadata(false));
/// <summary><see cref="DependencyProperty"/> for property <see cref="IsAnimation"/>.</summary>
public static readonly DependencyProperty IsAnimationProperty = IsAnimationPropertyKey.DependencyProperty;
}
}
using System;
using System.Windows;
using System.Windows.Threading;
namespace Proxy
{
public partial class DeltaNumberAnimator
{
private readonly DispatcherTimer timer = new DispatcherTimer();
private double source;
private double delta;
private double number;
public DeltaNumberAnimator()
{
timer.Tick += OnTick;
}
private void OnTick(object sender,EventArgs e)
{
if (NextStep())
{
timer.Stop();
IsAnimation = false;
}
}
private static void IntervalChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
((DeltaNumberAnimator)d).timer.Interval = (TimeSpan)e.NewValue;
}
private void SourceChanged(DependencyPropertyChangedEventArgs e)
{
source = (double)e.NewValue;
if (source == number)
{
timer.Stop();
IsAnimation = false;
return;
}
if (timer.Interval == TimeSpan.Zero ||
delta == 0d)
{
Number = source;
timer.Stop();
IsAnimation = false;
return;
}
if (!NextStep())
{
timer.Start();
IsAnimation = true;
}
}
// Changing Number by Delta towards Source.
// Returns true if the Source value is reached.
private bool NextStep()
{
if (number < source)
{
double next = number + delta;
if (next >= source)
{
Number = source;
return true;
}
else
{
Number = next;
return false;
}
}
else
{
double next = number - delta;
if (next <= source)
{
Number = source;
return true;
}
else
{
Number = next;
return false;
}
}
}
private static object CoerceDelta(DependencyObject d,object baseValue)
{
double num = (double)baseValue;
if (num < double.Epsilon && num > -double.Epsilon)
return 0d;
if (num > 0)
return baseValue;
return -num;
}
private static void DeltaChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
((DeltaNumberAnimator)d).delta = (double)e.NewValue;
}
private static void NumberChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
((DeltaNumberAnimator)d).number = (double)e.NewValue;
}
}
}
使用示例:
namespace DeltaNumber
{
public class ViewModel
{
public double NumberProperty { get; set; }
}
}
<Window x:Class="DeltaNumber.DeltaNumberTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeltaNumber" xmlns:proxy="clr-namespace:Proxy;assembly=Common"
mc:Ignorable="d"
Title="DeltaNumberTestWindow" Height="450" Width="800">
<FrameworkElement.DataContext>
<local:ViewModel/>
</FrameworkElement.DataContext>
<UniformGrid Columns="1">
<FrameworkElement.Resources>
<proxy:DeltaNumberAnimator x:Key="deltaAnimator"
Source="{Binding NumberProperty}"
Delta="1"
Interval="0:0:1"/>
</FrameworkElement.Resources>
<TextBlock Text="{Binding Number,Source={StaticResource deltaAnimator}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAnimation,Source={StaticResource deltaAnimator}}"
Value="True">
<Setter Property="Background" Value="LightGreen"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBox Text="{Binding NumberProperty}"/>
<TextBox Text="Any text. Used only to lose focus in an binded TextBox."/>
</UniformGrid>
</Window>