Adorner实现边框线条动画

在 WPF 中,Adorner 是一种特殊的装饰层,能够在 UI 元素之上绘制视觉效果。常用于提供视觉反馈或装饰功能,例如焦点指示、拖放效果等。

自定义 Adorne 类

要创建自定义 Adorner,需要继承 Adorner 类并重写 OnRender 方法。在 OnRender 方法中,您可以使用 DrawingContext 绘制自定义图形。

示例:创建带动画边框的 Adorner

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
public class AnimatedBorderAdorner : Adorner
{
private double _animationProgress;
private AnimationClock _animationClock;
public AnimatedBorderAdorner(UIElement adornedElement) : base(adornedElement)
{
StartAnimation();
}
private void StartAnimation()
{
DoubleAnimation animation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(2)));
animation.RepeatBehavior = RepeatBehavior.Forever;
//animation.AutoReverse = true;
animation.AutoReverse = false;
// Create a clock for the animation and start it
_animationClock = animation.CreateClock();
_animationClock.CurrentTimeInvalidated += (s, e) =>
{
if (_animationClock.CurrentProgress.HasValue)
{
_animationProgress = _animationClock.CurrentProgress.Value;
// Request a redraw
InvalidateVisual();
}
ApplyAnimationClock(AnimationProgressProperty, _animationClock);
};
}
public double AnimationProgress
{
get { return (double)GetValue(AnimationProgressProperty); }
set { SetValue(AnimationProgressProperty, value); }
}
// Using a DependencyProperty as the backing store for AnimationProgress. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AnimationProgressProperty =
DependencyProperty.Register("AnimationProgress", typeof(double), typeof(AnimatedBorderAdorner), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize);
// Calculate the dash offset based on the animation progress
double dashOffset = - adornedElementRect.Width * _animationProgress;
// Create a new Pen object for each render
Pen pen = new Pen(Brushes.ForestGreen, 2);
FormattedText ft = new FormattedText("ON",
CultureInfo.CurrentCulture,
FlowDirection.RightToLeft,
new Typeface(new FontFamily("微软雅黑"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal),
8,
Brushes.Green,
96);
drawingContext.DrawText(ft, new Point(adornedElementRect.TopRight.X - 2, adornedElementRect.TopRight.Y));
pen.DashStyle = new DashStyle(new double[] {adornedElementRect.Width / 4, adornedElementRect.Width / 4}, dashOffset);
drawingContext.DrawRectangle(null, pen, adornedElementRect);
}
}

应用 Adorner

为了将 Adorner 应用到 UI 元素,需要获取该元素的 AdornerLayer,然后添加或移除 Adorner

示例:在 ToggleButton 上应用 Adorner

private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
ToggleButton toggleButton = sender as ToggleButton;
AdornerLayer layer = AdornerLayer.GetAdornerLayer(toggleButton);
if (layer != null)
{
Adorner[] adorners = layer.GetAdorners(toggleButton);
AnimatedBorderAdorner existingAdorner = adorners?.OfType<AnimatedBorderAdorner>().FirstOrDefault();
if (existingAdorner != null)
{
layer.Remove(existingAdorner);
}
else
{
layer.Add(new AnimatedBorderAdorner(toggleButton));
}
}
}

XAML 中定义 UI 元素

在 XAML 中,可以使用 AdornerDecorator 包裹目标 UI 元素,以确保 Adorner 能够正确显示。

示例:定义 ToggleButton

<Window x:Class="YourNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<AdornerDecorator>
<ToggleButton Width="100" Height="50" Content="Toggle" Click="ToggleButton_Click"/>
</AdornerDecorator>
</Grid>
</Window>

重要属性和方法

  • AdornerLayer:用于管理 Adorner 的层。可以通过 AdornerLayer.GetAdornerLayer(UIElement) 方法获取。
  • ApplyAnimationClock:将动画应用到 DependencyProperty,以便在动画进度变化时触发重绘。
  • InvalidateVisual:请求重绘 Adorner

关键点总结

  1. 创建自定义 Adorner:继承 Adorner 类,重写 OnRender 方法。
  2. 添加动画:使用 DoubleAnimationAnimationClockAdorner 添加动画效果。
  3. 管理 Adorner:通过 AdornerLayer 添加或移除 Adorner
  4. 确保视觉效果:在 XAML 中使用 AdornerDecorator 包裹目标 UI 元素。
  5. 性能优化:在 OnRender 方法中避免复杂计算和创建大量对象,尽量复用资源。

通过这些步骤和示例,您可以在 WPF 应用程序中创建和管理复杂的 Adorner,以实现丰富的视觉效果和用户交互。

posted @   非法关键字  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略
历史上的今天:
2020-05-28 监听文件夹
2018-05-28 Easyloggingpp的使用
2018-05-28 Dapper简介
点击右上角即可分享
微信分享提示