原文:
Shape流动效果
<Window x:Class="MvvmLight1.MainWindow" 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:localBehavior="clr-namespace:MvvmLight1" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ignore="http://www.ignore.com" mc:Ignorable="d ignore" Height="400" Width="600" Title="MVVM Light Application" DataContext="{Binding Main, Source={StaticResource Locator}}"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Skins/MainSkin.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <StackPanel> <Ellipse StrokeDashArray="2,4" Stroke="Red" StrokeThickness="3" Height="100" Width="100"> <i:Interaction.Behaviors> <localBehavior:FluidBehavior FlowRate="{Binding ElementName=FlowRate,Path=Value}" WhetherFluid="{Binding ElementName=FluidCheckBox, Path=IsChecked}"/> </i:Interaction.Behaviors> </Ellipse> <Rectangle StrokeDashArray="1,2" Stroke="Blue" StrokeThickness="3" Height="100" Width="100"> <i:Interaction.Behaviors> <localBehavior:FluidBehavior FlowRate="{Binding ElementName=FlowRate,Path=Value}" WhetherFluid="{Binding ElementName=FluidCheckBox, Path=IsChecked}"/> </i:Interaction.Behaviors> </Rectangle> <Path x:Name="MyPath" StrokeThickness="3" StrokeDashArray="5,10" Stroke="Black"> <i:Interaction.Behaviors> <localBehavior:FluidBehavior FlowRate="{Binding ElementName=FlowRate,Path=Value}" WhetherFluid="{Binding ElementName=FluidCheckBox, Path=IsChecked}"/> </i:Interaction.Behaviors> <Path.Data> <PathGeometry Figures="M 10,100 C 10,300 300,-160 300,100" /> </Path.Data> </Path> <StackPanel> <CheckBox x:Name="FluidCheckBox" Content="流动效果"/> <Slider x:Name="FlowRate" Minimum="1" Maximum="10"/> <TextBlock Text="{Binding ElementName=FlowRate,Path=Value}"/> </StackPanel> </StackPanel> </Window>
由Xaml可以看出核心就是一个FluidBehavior,效果,就不过多阐述了
最核心的就是用一个定时器对于Shape的StrokeDashOffset进行改变,其中抽象FlowRate以及WhetherFluid用于控制流动速率以及是否流动
using System; using System.Windows; using System.Windows.Interactivity; using System.Windows.Shapes; using System.Windows.Threading; namespace MvvmLight1 { /// <summary> /// 流动行为 /// </summary> public class FluidBehavior : Behavior<Shape> { #region 依赖属性 /// <summary> /// 流动速度 /// </summary> public int FlowRate { get { return (int)GetValue(FlowRateProperty); } set { SetValue(FlowRateProperty, value); } } // Using a DependencyProperty as the backing store for FlowRate. This enables animation, styling, binding, etc... public static readonly DependencyProperty FlowRateProperty = DependencyProperty.Register("FlowRate", typeof(int), typeof(FluidBehavior), new PropertyMetadata(1)); /// <summary> /// 是否流动 /// </summary> public bool WhetherFluid { get { return (bool)GetValue(WhetherFluidProperty); } set { SetValue(WhetherFluidProperty, value); } } // Using a DependencyProperty as the backing store for WhetherFluid. This enables animation, styling, binding, etc... public static readonly DependencyProperty WhetherFluidProperty = DependencyProperty.Register("WhetherFluid", typeof(bool), typeof(FluidBehavior), new PropertyMetadata(true, OnWhetherFluidChanged)); private static void OnWhetherFluidChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var behavior = d as FluidBehavior; if (Convert.ToBoolean(e.NewValue)) { behavior._timer.Start(); } else { behavior._timer.Stop(); } } #endregion protected override void OnAttached() { base.OnAttached(); Fluid(); } private readonly DispatcherTimer _timer = new DispatcherTimer(); //流动 private void Fluid() { _timer.Tick += (sender, e) => { AssociatedObject.StrokeDashOffset -= FlowRate; }; _timer.Interval = TimeSpan.FromSeconds(1d / 60); if (WhetherFluid) { _timer.Start(); } } } }