在 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
。
關鍵點總結
- 建立自定義 Adorner:繼承
Adorner
類,重寫OnRender
方法。 - 新增動畫:使用
DoubleAnimation
和AnimationClock
為Adorner
新增動畫效果。 - 管理 Adorner:透過
AdornerLayer
新增或移除Adorner
。 - 確保視覺效果:在 XAML 中使用
AdornerDecorator
包裹目標 UI 元素。 - 效能最佳化:在
OnRender
方法中避免複雜計算和建立大量物件,儘量複用資源。
透過這些步驟和示例,您可以在 WPF 應用程式中建立和管理複雜的 Adorner,以實現豐富的視覺效果和使用者互動。