示例: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个人主页-哔哩哔哩视频

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54650.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

try microceph (by quqi99)

作者&#xff1a;张华 发表于&#xff1a;2024-09-24 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明(http://blog.csdn.net/quqi99) sudo snap install microceph --channelreef/stable sudo microceph clust…

一分钟掌握 Java11 新特性

1. 局部变量类型推断&#xff08;var&#xff09; Java 11 允许使用 var 关键字来推断局部变量的类型。 在 Java 11 中&#xff0c; var 关键字允许开发者在声明局部变量时省略类型&#xff0c;编译器会根据赋值自动推断类型。这使得代码更加简洁&#xff0c;尤其在类型复杂的…

【Linux】深度解析与实战应用:GCC/G++编译器入门指南

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制&#xff08;防止网络波动&#xff09;2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…

Winform—事件多播和事件联机响应

事件多播 多次点击连接事件按钮&#xff0c;再次点击button1 会出现多次调用 这个就是多播。 用法: this.button1.Click new System.EventHandler(this.button1_Click); //给button1加一次click事件&#xff0c;事件名称是button1_click 事件级联响应 事件的级联响应&#xf…

速通LLaMA3:《The Llama 3 Herd of Models》全文解读

文章目录 概览论文开篇IntroductionGeneral OverviewPre-TrainingPre-Training DataModel ArchitectureInfrastructure, Scaling, and EfficiencyTraining Recipe Post-TrainingResultsVision ExperimentsSpeech Experiments⭐Related WorkConclusionLlama 3 模型中的数学原理1…

【网站架构部署与优化】Nginx优化

文章目录 Nginx服务优化一、隐藏Nginx版本号&#xff0c;避免安全漏洞泄漏方法一&#xff1a;通过修改配置文件方法二&#xff1a;通过修改源码并重新编译安装 修改Nginx的用户和组修改用户与组 配置Nginx网页缓存时间配置Nginx连接保持的超时时间KeepAlive模式简介Nginx中的超…

细说硫酸钙防静电地板的材质结构和优势特点

防静电地板有全钢基材的、硫酸钙基材的、铝合金基材的&#xff0c;在一些防静电要求、承载要求、铺设要求、铺装效果要求很高的场合&#xff0c;如银行、电信机房、移动机房、智能化办公室、部队指挥中心&#xff0c;通常都会使用硫酸钙防静电地板。那么什么是硫酸钙防静电地板…

Python项目周报

项目名称: 网站数据爬取工具日期: 2024年9月16日 - 2024年9月22日 1. 项目背景 在当前数据驱动的时代&#xff0c;获取和分析数据已成为企业决策的重要组成部分。本项目旨在开发一款灵活且高效的Python爬虫工具&#xff0c;用于从指定网站抓取数据&#xff0c;并将其存储到Mo…

Access denied for user ‘root‘@‘114.254.154.110‘ (using password: YES)

navicat 连接远程服务器报错 1045 - Access denied for user root114.254.154.110 (using password: YES)报错解释&#xff1a; 这个错误表示客户端从IP地址114.254.154.110尝试以用户’root’身份连接到MySQL服务器时&#xff0c;被拒绝访问。原因可能是密码错误、用户’roo…

计算机毕业设计 二手图书交易系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

计算机毕业设计 基于Python的医疗预约与诊断系统 Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

arthas-阿里远程诊断工具神器一定要掌握

文章目录 1. 背景介绍2. 安装下载3. 常用命令4. 常见案例4.1 案例一&#xff1a;使用logger 实时修改某个类的日志级别、4.2 案例二&#xff1a;使用watch 查看方法输入输出参数4.3 案例三&#xff1a;使用 Arthas 实现在线代码热更新 1. 背景介绍 通常&#xff0c;本地开发环…

文件上传、amrkdown编辑器

一、文件上传 这里我以图片为例&#xff0c;进行上传&#xff0c;上传到阿里云oss&#xff08;对象存在中&#xff09; 首先&#xff0c;我们先梳理一下&#xff0c;图片上传的流程 1、前端选择文件&#xff0c;提交文件 前端提交文件&#xff0c;我们可以使用ElementUI中的…

蓝队技能-应急响应篇Web内存马查杀JVM分析Class提取诊断反编译日志定性

知识点&#xff1a; 1、应急响应-Web内存马-定性&排查 2、应急响应-Web内存马-分析&日志 注&#xff1a;传统WEB类型的内存马只要网站重启后就清除了。 演示案例-蓝队技能-JAVA Web内存马-JVM分析&日志URL&内存查杀 0、环境搭建 参考地址&#xff1a;http…

有关 签到/签退 业务逻辑 的梳理与学习

导言 最近搞到了个签到管理&#xff0c;其中的业务逻辑感觉有点复杂(可能是我的方向不对),虽然是实现了&#xff0c;不过代码和逻辑很多&#xff0c;也有些乱&#xff0c;想趁着还记得逻辑来记录梳理一下&#xff0c;看看自己以后有没有更好的思路&#xff0c;或者有大佬有思路…

Go Sonyflake学习与使用

文章目录 Sonyflake 特点Sonyflake ID 结构Sonyflake 使用场景Sonyflake 与 Snowflake 的对比Sonyflake 的实现安装 Sonyflake 库注意1. panic: no point解决方法&#xff1a; 2. panic: memory解决方法&#xff1a; 示例代码中的改进 Sonyflake 是一种分布式唯一 ID 生成器&am…

Pillow:Python图像处理库详解

Pillow&#xff08;之前称为PIL&#xff0c;Python Imaging Library&#xff09;是一个开源的Python图像处理库&#xff0c;它提供了广泛的文件格式支持、强大的图像处理能力和易于使用的API。Pillow可以处理几乎所有类型的图像文件&#xff0c;并且可以进行复杂的图像操作&…

[C#]winform 使用opencvsharp实现玉米粒计数

【算法介绍】 这段代码是使用OpenCvSharp库&#xff08;OpenCV的C#封装&#xff09;对图像进行处理&#xff0c;主要流程包括图像的二值化、腐蚀操作、距离变换、轮廓检测&#xff0c;并在原图上标出检测到的轮廓位置及数量。下面是对代码的详细解读&#xff1a; 初始化&…

在 Webpack 中配置多入口应用并实现公共依赖的提取

1. 配置多入口点 首先&#xff0c;在 webpack.config.js 文件中定义多个入口点。你可以通过对象形式来指定多个入口点&#xff0c;每个入口点对应一个输出文件。 const path require(path);module.exports {entry: {app1: ./src/app1/index.js,app2: ./src/app2/index.js},…