当前位置: 首页 > news >正文

示例:WPF中Grid显示网格线的几种方式

一、目的:介绍一下WPF中Grid显示网格线的几种方式


二、几种方式


1、重写OnRender绘制网格线(推荐)

效果如下:

实现方式如下:

    public class LineGrid : Grid{private readonly Pen _pen;public LineGrid(){_pen = new Pen(SystemColors.ActiveBorderBrush, 1);_pen.Freeze();}protected override void OnRender(DrawingContext dc){base.OnRender(dc);foreach (RowDefinition item in this.RowDefinitions){dc.DrawLine(_pen, new Point(0, item.Offset), new Point(this.ActualWidth, item.Offset));}dc.DrawLine(_pen, new Point(0, this.ActualHeight), new Point(this.ActualWidth, this.ActualHeight));foreach (ColumnDefinition item in this.ColumnDefinitions){dc.DrawLine(_pen, new Point(item.Offset, 0), new Point(item.Offset, this.ActualHeight));}dc.DrawLine(_pen, new Point(this.ActualWidth, 0), new Point(this.ActualWidth, this.ActualHeight));}}
                    <local:LineGrid Margin="50"><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="100" /></Grid.ColumnDefinitions><TextBlockGrid.Row="0"Grid.RowSpan="2"Grid.Column="5"Margin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"Background="White"Text="LineGrid" /><LabelMargin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"HorizontalContentAlignment="Center"VerticalContentAlignment="Center"Background="White"Content="Center"FontSize="50" /></local:LineGrid>

优点:通过OnRender绘制复杂度低,性能较好

缺点:需要单独定义LineGrid类重写OnRender ,但相对来说实现比较简单,复用性比较高

2、使用ShowGridLines属性

效果如下:

 实现代码
                    <Grid Margin="50" ShowGridLines="True"><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="100" /></Grid.ColumnDefinitions><TextBlockGrid.Row="0"Grid.RowSpan="2"Grid.Column="5"Margin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"Background="White"Text="LineGrid" /><LabelMargin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"HorizontalContentAlignment="Center"VerticalContentAlignment="Center"Background="White"Content="Center"FontSize="50" /></Grid>

优点:Grid自带功能,直接设置 ShowGridLines="True"即可

缺点:样式固定且单一,一般来说是不能满足需求

3、使用Adorner绘制

效果如下:

实现代码:
定义Adorner
    public class GridLineAdorner : Adorner{public GridLineAdorner(UIElement adornedElement) : base(adornedElement){}protected override void OnRender(DrawingContext dc){base.OnRender(dc);Grid grid = this.AdornedElement as Grid;if (grid == null)return;Pen pen = new Pen(SystemColors.HighlightBrush, 1);foreach (RowDefinition item in grid.RowDefinitions){dc.DrawLine(pen, new Point(0, item.Offset), new Point(this.ActualWidth, item.Offset));}dc.DrawLine(pen, new Point(0, grid.ActualHeight), new Point(this.ActualWidth, this.ActualHeight));foreach (ColumnDefinition item in grid.ColumnDefinitions){dc.DrawLine(pen, new Point(item.Offset, 0), new Point(item.Offset, this.ActualHeight));}dc.DrawLine(pen, new Point(this.ActualWidth, 0), new Point(this.ActualWidth, this.ActualHeight));}}

(注:这部分目前没有实现Rowspan和Columnspan网线的遮挡,有需求的可以使用PushClip方式实现) 

 Xaml中添加代码
        <AdornerDecorator><Grid Margin="50" Loaded="GridLine_Loaded"><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /><RowDefinition Height="50" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="100" /></Grid.ColumnDefinitions><TextBlockGrid.Row="0"Grid.RowSpan="2"Grid.Column="5"Margin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"Background="White"Text="LineGrid" /><LabelMargin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"HorizontalContentAlignment="Center"VerticalContentAlignment="Center"Background="White"Content="Center"FontSize="50" /></Grid></AdornerDecorator>
在Loaded时给Grid添加Adoner
        private void GridLine_Loaded(object sender, RoutedEventArgs e){Grid grid = sender as Grid;GridLineAdorner gridLineAdorner = new GridLineAdorner(grid);var layer = AdornerLayer.GetAdornerLayer(grid);layer.Add(gridLineAdorner);}

 优点:定义成Adorner复用性比较高

 缺点:实现和添加相对复杂些,但一劳永逸,也可以把Loaded部分封装成附加属性调用这样就可以不用单独处理事件

4、使用GridLineAttach附加属性,添加Border的方式绘制

效果如下:

实现代码:
定义附加属性 
    public class GridLineAttach{public static bool GetUse(DependencyObject obj){return (bool)obj.GetValue(UseProperty);}public static void SetUse(DependencyObject obj, bool value){obj.SetValue(UseProperty, value);}public static readonly DependencyProperty UseProperty =DependencyProperty.RegisterAttached("Use", typeof(bool), typeof(GridLineAttach), new PropertyMetadata(default(bool), OnUseChanged));static public void OnUseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Grid grid = d as Grid;if (grid == null)return;bool n = (bool)e.NewValue;grid.Loaded -= Grid_Loaded;if (n)grid.Loaded += Grid_Loaded;}private static void Grid_Loaded(object sender, RoutedEventArgs e){Grid grid = sender as Grid;var controls = grid.Children;var count = controls.Count;for (int i = 0; i < count; i++){var item = controls[i] as FrameworkElement;var border = new Border(){BorderBrush = SystemColors.ActiveBorderBrush,BorderThickness = new Thickness(1)};var row = Grid.GetRow(item);var column = Grid.GetColumn(item);var rowspan = Grid.GetRowSpan(item);var columnspan = Grid.GetColumnSpan(item);Grid.SetRow(border, row);Grid.SetColumn(border, column);Grid.SetRowSpan(border, rowspan);Grid.SetColumnSpan(border, columnspan);grid.Children.Add(border);}}}
给Grid添加附加属性
                    <Grid Margin="50" local:GridLineAttach.Use="True"><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="50" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="100" /></Grid.ColumnDefinitions><TextBlockGrid.Row="0"Grid.RowSpan="2"Grid.Column="5"Margin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"Background="White"Text="LineGrid" /><LabelMargin="1"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"HorizontalContentAlignment="Center"VerticalContentAlignment="Center"Background="White"Content="Center"FontSize="50" /><TextBlock Text="1" Grid.Row="1"/></Grid>

优点:定义成附加属性复用性比较高

缺点:额外添加了Border元素,对于数据量比较大的情况增加了渲染压力

需要了解的知识点 

Grid 类 (System.Windows.Controls) | Microsoft Learn

Adorner 类 (System.Windows.Documents) | Microsoft Learn

AdornerLayer 类 (System.Windows.Documents) | Microsoft Learn

AdornerDecorator 类 (System.Windows.Documents) | Microsoft Learn

UIElement.OnRender(DrawingContext) Method (System.Windows) | Microsoft Learn

Grid.ShowGridLines Property (System.Windows.Controls) | Microsoft Learn

Border 类 (System.Windows.Controls) | Microsoft Learn

System.Windows.Controls 命名空间 | Microsoft Learn

控件库 - WPF .NET Framework | Microsoft Learn

WPF 介绍 | Microsoft Learn

XAML概述 - WPF .NET | Microsoft Learn

Windows Presentation Foundation 简介 - WPF .NET | Microsoft Learn

使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn

源码地址

GitHub - HeBianGu/WPF-ControlDemo: 示例

GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库

GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库

了解更多

适用于 .NET 8 的 WPF 的新增功能 - WPF .NET | Microsoft Learn

适用于 .NET 7 的 WPF 的新增功能 - WPF .NET | Microsoft Learn

System.Windows.Controls 命名空间 | Microsoft Learn

Reference Source

Sysinternals - Sysinternals | Microsoft Learn

Windows app development documentation - Windows apps | Microsoft Learn

欢迎使用 Expression Blend | Microsoft Learn

https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/?view=netdesktop-7.0&WT.mc_id=MVP_380318

https://github.com/HeBianGu

HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 常见服务端口号和中文大全
  • 2409js,学习js1
  • 【安当产品应用案例100集】017-助力软件服务商高效集成多因素认证
  • 深入探讨 Flask、Gunicorn、Gevent 与 RecursionError:事件循环与 Monkey Patching 的正确使用
  • 常见区块链数据模型介绍
  • 深圳前海壹方汇的免费停车点探寻
  • linux之进程信号
  • ETCD学习使用
  • 解决跨域问题的方法
  • 关于模型外推能力的论文
  • 深入探秘 WorkManager:Android 异步任务管理的强大工具
  • 面试真题 | 小红书-C++引擎架构
  • vscode 代码格式setting设置
  • Java语法-类和对象(上)
  • java jdk8内存序列化为xml
  • 收藏网友的 源程序下载网
  • 【node学习】协程
  • 2017-09-12 前端日报
  • java8-模拟hadoop
  • Java精华积累:初学者都应该搞懂的问题
  • Lsb图片隐写
  • React系列之 Redux 架构模式
  • 基于web的全景—— Pannellum小试
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 一、python与pycharm的安装
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 06-01 点餐小程序前台界面搭建
  • Linux权限管理(week1_day5)--技术流ken
  • # Maven错误Error executing Maven
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #if #elif #endif
  • #stm32整理(一)flash读写
  • ${ }的特别功能
  • (09)Hive——CTE 公共表达式
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (27)4.8 习题课
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (BFS)hdoj2377-Bus Pass
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (ZT)一个美国文科博士的YardLife
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (二十三)Flask之高频面试点
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (回溯) LeetCode 131. 分割回文串
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (一)模式识别——基于SVM的道路分割实验(附资源)
  • (转)重识new
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析