博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF中ListView添加网格线
阅读量:6638 次
发布时间:2019-06-25

本文共 10258 字,大约阅读时间需要 34 分钟。

[ContentProperty("Target")]    public class GridLineDecorator : FrameworkElement    {        private ListView _target;        private DrawingVisual _gridLinesVisual = new DrawingVisual();        private GridViewHeaderRowPresenter _headerRowPresenter = null;        public GridLineDecorator()        {            this.AddVisualChild(_gridLinesVisual);            this.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler(OnScrollChanged));        }        #region GridLineBrush        ///           /// GridLineBrush Dependency Property          ///           public static readonly DependencyProperty GridLineBrushProperty =            DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridLineDecorator),                new FrameworkPropertyMetadata(Brushes.LightGray,                    new PropertyChangedCallback(OnGridLineBrushChanged)));        ///           /// Gets or sets the GridLineBrush property.  This dependency property           /// indicates ....          ///           public Brush GridLineBrush        {            get { return (Brush)GetValue(GridLineBrushProperty); }            set { SetValue(GridLineBrushProperty, value); }        }        ///           /// Handles changes to the GridLineBrush property.          ///           private static void OnGridLineBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        {            ((GridLineDecorator)d).OnGridLineBrushChanged(e);        }        ///           /// Provides derived classes an opportunity to handle changes to the GridLineBrush property.          ///           protected virtual void OnGridLineBrushChanged(DependencyPropertyChangedEventArgs e)        {            DrawGridLines();        }        #endregion        #region Target        public ListView Target        {            get { return _target; }            set            {                if (_target != value)                {                    if (_target != null) Detach();                    RemoveVisualChild(_target);                    RemoveLogicalChild(_target);                    _target = value;                    AddVisualChild(_target);                    AddLogicalChild(_target);                                     if (_target != null) Attach();                    InvalidateMeasure();                }            }        }        private void GetGridViewHeaderPresenter()        {            if (Target == null)            {                _headerRowPresenter = null;                return;            }            _headerRowPresenter = Target.GetDesendentChild
(); } #endregion #region DrawGridLines private void DrawGridLines() { if (Target == null) return; if (_headerRowPresenter == null) return; var itemCount = Target.Items.Count; if (itemCount == 0) return; var gridView = Target.View as GridView; if (gridView == null) return; // 获取drawingContext var drawingContext = _gridLinesVisual.RenderOpen(); var startPoint = new Point(0, 0); // 为了对齐到像素的计算参数,否则就会看到有些线是模糊的 var dpiFactor = this.GetDpiFactor(); var pen = new Pen(this.GridLineBrush, 1 * dpiFactor); var halfPenWidth = pen.Thickness / 2; var guidelines = new GuidelineSet(); // 计算表头的偏移量和大小 var headerOffset = _headerRowPresenter.TranslatePoint(startPoint, this); var headerSize = _headerRowPresenter.RenderSize; var headerBottomY = headerOffset.Y + headerSize.Height; // 计算ScrollViewer的可视区域大小 var item0 = _target.ItemContainerGenerator.ContainerFromIndex(0); if (item0 == null) return; var scrollViewer = item0.GetAncestor
(); if (scrollViewer == null) return; var contentElement = scrollViewer.Content as UIElement; var maxLineX = scrollViewer.ViewportWidth; var maxLineY = headerBottomY + contentElement.RenderSize.Height; var vLineY = 0.0; // 画横线 for (int i = 0; i < itemCount; i++) { var item = Target.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem; if (item != null) { var renderSize = item.RenderSize; var offset = item.TranslatePoint(startPoint, this); var hLineX1 = offset.X; var hLineX2 = offset.X + renderSize.Width; var hLineY = offset.Y + renderSize.Height; vLineY = hLineY; // 小于视图起始位置的不绘制 if (hLineY <= headerBottomY) continue; // 大于视图结束位置之后的不绘制 if (hLineY > maxLineY) break; // 如果大于横向宽度,取横向宽度 if (hLineX2 > maxLineX) hLineX2 = maxLineX; // 加入参考线,对齐到像素 guidelines.GuidelinesY.Add(hLineY + halfPenWidth); drawingContext.PushGuidelineSet(guidelines); drawingContext.DrawLine(pen, new Point(hLineX1, hLineY), new Point(hLineX2, hLineY)); drawingContext.Pop(); } } //画竖线 var columns = gridView.Columns; var vLineX = headerOffset.X; if (vLineY > maxLineY) vLineY = maxLineY; foreach (var column in columns) { var columnWidth = column.GetColumnWidth(); vLineX += columnWidth; if (vLineX > maxLineX) break; //加入参考线,对齐到像素 guidelines.GuidelinesX.Add(vLineX + halfPenWidth); drawingContext.PushGuidelineSet(guidelines); drawingContext.DrawLine(pen, new Point(vLineX, headerBottomY), new Point(vLineX, vLineY)); drawingContext.Pop(); } drawingContext.Close(); } #endregion #region Overrides to show Target and grid lines protected override int VisualChildrenCount { get { return Target == null ? 1 : 2; } } protected override System.Collections.IEnumerator LogicalChildren { get { yield return Target; } } protected override Visual GetVisualChild(int index) { if (index == 0) return _target; if (index == 1) return _gridLinesVisual; throw new IndexOutOfRangeException(string.Format("Index of visual child '{0}' is out of range", index)); } protected override Size MeasureOverride(Size availableSize) { if (Target != null) { Target.Measure(availableSize); return Target.DesiredSize; } return base.MeasureOverride(availableSize); } protected override Size ArrangeOverride(Size finalSize) { if (Target != null) Target.Arrange(new Rect(new Point(0, 0), finalSize)); return base.ArrangeOverride(finalSize); } #endregion #region Handle Events private void Attach() { _target.Loaded += OnTargetLoaded; _target.Unloaded += OnTargetUnloaded; _target.SizeChanged += OnTargetSizeChanged; _target.DragEnter += _target_DragEnter; } void _target_DragEnter(object sender, DragEventArgs e) { DrawGridLines(); } private void Detach() { _target.Loaded -= OnTargetLoaded; _target.Unloaded -= OnTargetUnloaded; _target.SizeChanged -= OnTargetSizeChanged; } private void OnTargetLoaded(object sender, RoutedEventArgs e) { if (_headerRowPresenter == null) GetGridViewHeaderPresenter(); DrawGridLines(); } private void OnTargetUnloaded(object sender, RoutedEventArgs e) { DrawGridLines(); } private void OnTargetSizeChanged(object sender, SizeChangedEventArgs e) { DrawGridLines(); } private void OnScrollChanged(object sender, RoutedEventArgs e) { DrawGridLines(); } #endregion }

  GridViewColumnHelper

internal  static class GridViewColumnHelper    {        private static PropertyInfo DesiredWidthProperty =           typeof(GridViewColumn).GetProperty("DesiredWidth", BindingFlags.NonPublic | BindingFlags.Instance);        public static double GetColumnWidth(this GridViewColumn column)        {            return (double.IsNaN(column.Width)) ? (double)DesiredWidthProperty.GetValue(column, null) : column.Width;        }      }

  

VisualService

public static class VisualService    {        public static double GetDpiFactor(this Visual target)        {            var source = PresentationSource.FromVisual(target);            return source == null ? 1.0 : 1 / source.CompositionTarget.TransformToDevice.M11;        }        public static T GetAncestor
(this DependencyObject target) where T : DependencyObject { var parent = VisualTreeHelper.GetParent(target); if (parent is T) return (T)parent; if (parent != null) return parent.GetAncestor
(); return null; } public static T GetDesendentChild
(this DependencyObject target) where T : DependencyObject { var childCount = VisualTreeHelper.GetChildrenCount(target); if (childCount == 0) return null; for (int i = 0; i < childCount; i++) { var current = VisualTreeHelper.GetChild(target, i); if (current is T) return (T)current; var desendent = current.GetDesendentChild
(); if (desendent != null) return desendent; } return null; } }

 

 

...

 

转载于:https://www.cnblogs.com/saybookcat/p/5190925.html

你可能感兴趣的文章
Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
查看>>
@Resource annotation is not supported on static fields
查看>>
JAVA面试准备(java基础部分2)
查看>>
快速启动zabbix监控服务集群
查看>>
模仿,anjularjs 双向绑定 ,纯javascript实现
查看>>
自制监控系统
查看>>
window 2008 下 安装域管理并且控制qq和usb
查看>>
WCF SOA服务应用
查看>>
Sea.js的使用方法(包含2.0以上)
查看>>
centos 6的网卡坑
查看>>
Unity性能优化-内存优化
查看>>
oracle 内存二 SGA
查看>>
跟我一起学QT5:布局管理
查看>>
HTTP 之 一次完整的http请求处理过程
查看>>
LVS 之 高可用性
查看>>
zookeeper安装
查看>>
Java冒泡排序之我见
查看>>
Powercli批量添加iscsi软适配器
查看>>
Python OpenCV学习笔记之:处理鼠标事件
查看>>
MXNet动手学深度学习笔记:卷积神经网络实现
查看>>