示例: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,一经查实,立即删除!

相关文章

【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、消费者…

速通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…

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

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

计算机毕业设计 二手图书交易系统 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;或者有大佬有思路…

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

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

Ubuntu22.04安装GNSS数据处理软件GAMIT/GLOBK

由于微信公众号改变了推送规则&#xff0c;为了每次新的推送可以在第一时间出现在您的订阅列表中&#xff0c;记得将本公众号设为星标或置顶喔~ 手把手带您安装gamit/globk软件~ &#x1f33f;前言 受朋友之托&#xff0c;出一期Ubuntu22.04安装GNSS数据处理软件——gamit软件…

【论文笔记】Are Large Kernels Better Teacheres than Transformers for ConvNets

Abstract 本文提出蒸馏中小核ConvNet做学生时&#xff0c;与Transformer相比&#xff0c;大核ConvNet因其高效的卷积操作和紧凑的权重共享&#xff0c;使得其做教师效果更好&#xff0c;更适合资源受限的应用。 用蒸馏从Transformers蒸到小核ConvNet的效果并不好&#xff0c;原…

MySQL篇(存储过程 触发器 存储函数)(持续更新迭代)

目录 一、存储过程 1. 简介 2. 特点 3. 语法 3.1. 创建 3.2. 调用 3.3. 查看 3.4. 删除 4. 示例 二、变量 1. 简介 2. 系统变量 2.1. 查看系统变量 2.2. 设置系统变量 2.3. 演示示例 3. 用户定义变量 3.1. 赋值 方式一 方式二 3.2. 使用 3.3. 演示示例 4.…

Rust - 字符串:str 与 String

在其他语言中&#xff0c;字符串通常都会比较简单&#xff0c;例如 “hello, world” 就是字符串章节的几乎全部内容了。 但是Rust中的字符串与其他语言有所不同&#xff0c;若带着其他语言的习惯来学习Rust字符串&#xff0c;将会波折不断。 所以最好先忘记脑中已有的关于字…

华为---代理ARP简介及示例配置

目录 1. 概念 2. 前提条件 3. 使用环境 4. 工作过程 5. 优点 6. 缺点 7. 示例配置 7.1 示例场景 7.2基本配置 7.3 配置端口隔离 7.4 开启代理ARP 7.4.1 VLAN内代理ARP 7.4.2 VLAN间代理ARP 7.4.3路由式ARP代理 1. 概念 代理ARP&#xff08;Proxy ARP&#xff09;&…

C#使用实体类Entity Framework Core操作mysql入门:从数据库反向生成模型

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

matlab恢复默认窗口布局

1.点击主页&#xff0c;选择布局 2.选择默认&#xff0c;即可恢复到默认的窗口布局

LIN总线CAPL函数—— 设置LIN报文字节间隔长度(linSetInterByteSpace)

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

利士策分享,如何培养良好的工作习惯?

利士策分享&#xff0c;如何培养良好的工作习惯&#xff1f; 在这个快节奏、高压力的职场环境中&#xff0c;培养良好的工作习惯不仅关乎个人职业发展的顺畅度&#xff0c; 更是提升工作效率、保持身心健康的关键。 以下是一些实用的建议&#xff0c;帮助你在日常工作中逐步构…