WPF使用装饰器实现SAP焦点样式

SAP当焦点进入控件时,会在控件的四个角上出现红框,见下图示例。

要实现这样的功能是有点难度的,幸好WPF提供了装饰器这个玩意,实现起来就容易了。
先说一下思路:
1.重写控件的装饰器;
2.指定窗体上的所有控件使用自定义的装饰器;
3.当控件获得焦点时显示装饰器。

现在,第一步重写装饰器Adorner,主要是绘制四个角边框的方法

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Documents; using System.Windows; using System.Windows.Media; namespace ControlAdorner { public class SimpleAdorner:Adorner { public SimpleAdorner(UIElement adornedElement):base(adornedElement) {} protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize); Pen renderPen = new Pen(new SolidColorBrush(Colors.Red), 1.0); // Draw a circle at each corner. drawingContext.DrawLine(renderPen, new Point(adornedElementRect.TopLeft.X - 3, adornedElementRect.TopLeft.Y - 3), new Point(adornedElementRect.TopLeft.X + 5, adornedElementRect.TopLeft.Y - 3)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.TopLeft.X - 3, adornedElementRect.TopLeft.Y - 3), new Point(adornedElementRect.TopLeft.X - 3, adornedElementRect.TopLeft.Y + 5)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.TopRight.X + 3, adornedElementRect.TopRight.Y - 3), new Point(adornedElementRect.TopRight.X - 5, adornedElementRect.TopRight.Y - 3)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.TopRight.X + 3, adornedElementRect.TopRight.Y - 3), new Point(adornedElementRect.TopRight.X + 3, adornedElementRect.TopRight.Y + 5)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.BottomLeft.X - 3, adornedElementRect.BottomLeft.Y + 3), new Point(adornedElementRect.BottomLeft.X + 5, adornedElementRect.BottomLeft.Y + 3)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.BottomLeft.X - 3, adornedElementRect.BottomLeft.Y + 3), new Point(adornedElementRect.BottomLeft.X - 3, adornedElementRect.BottomLeft.Y - 5)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.BottomRight.X + 3, adornedElementRect.BottomRight.Y + 3), new Point(adornedElementRect.BottomRight.X - 5, adornedElementRect.BottomRight.Y + 3)); drawingContext.DrawLine(renderPen, new Point(adornedElementRect.BottomRight.X + 3, adornedElementRect.BottomRight.Y + 3), new Point(adornedElementRect.BottomRight.X + 3, adornedElementRect.BottomRight.Y - 5)); } } }


第二步,先创建一个窗体,然后拖曳一些控件,如上图;然后遍历控件,为控件指定自定义装饰器

public partial class MainWindow : Window { //AdornerLayer layer1; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { AdornerLayer layer1 = AdornerLayer.GetAdornerLayer(this.Content as Grid); List<Visual> list = new List<Visual>(); AppHelper.EnumVisual(list, this); AppHelper.AddAdorner(list, layer1); } }


辅助类

public class AppHelper { /// <summary> /// 枚举可视控件 /// </summary> /// <param name="list"></param> /// <param name="myVisual"></param> /// <returns></returns> public static List<Visual> EnumVisual(List<Visual> list, Visual myVisual) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++) { Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i); if (childVisual != null) { if (childVisual is TextBox || childVisual is ComboBox || childVisual is CheckBox || childVisual is ListBox || childVisual is Button || childVisual is RadioButton) { list.Add(childVisual); } else { EnumVisual(list, childVisual); } } } return list; } /// <summary> /// 添加装饰层和装饰器 /// </summary> /// <param name="list"></param> /// <param name="layer"></param> public static void AddAdorner(List<Visual> list, AdornerLayer layer) { foreach (Visual v in list) { UIElement ele = v as UIElement; ele.GotFocus += (s, e2) => { if (ele.IsFocused) { ClearAdorners(list, ele, layer); layer.Add(new SimpleAdorner(ele)); } }; } } /// <summary> /// 清除装饰器 /// </summary> /// <param name="list"></param> /// <param name="element"></param> /// <param name="layer"></param> public static void ClearAdorners(List<Visual> list, UIElement element, AdornerLayer layer) { foreach (Visual v in list) { UIElement ele = v as UIElement; if (ele != element) { Adorner[] ads = layer.GetAdorners(ele); if (ads != null) { for (int i = ads.Length - 1; i >= 0; i--) { layer.Remove(ads[i]); } } } } } }


项目源代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值