WPF利用附加屬性修改ShowGridLines效果


1.思路主要代碼

wpf的gridline原本效果是虛線類型的。有時候需要設計成表格形式的,因此有了用附加屬性來自動繪制邊框線的想法。

思路:繪制Line並添加到grid的children里,但效果並不理想,會出現鋸齒,像素對齊,模糊等問題。

UseLayoutRounding="False"
SnapsToDevicePixels="True"

RenderOptions.EdgeModeProperty 貌似都沒起作用。

於是想到了用border來實現,簡單又實用吧 哈哈。

大致思路如下:繪制border的左邊框和上邊框,在邊界的時候考慮邊界封閉。然后將border平移一半的距離。這樣邊框就居中並且包圍了所有的線。

 

主要代碼如下:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace 用附加屬性修改Grid的邊框
{
    public class GridHelper
    {
        private static void RefreshGrid(Grid grid, int lineWidth, Brush color)
        {
            for (var i = grid.Children.Count - 1; i > 0; i--)
            {
                var child = grid.Children[i];

                var bd = child as Border;
                if (bd != null && bd.Tag != null && bd.Tag.ToString() == "gridline")
                {
                    grid.Children.Remove(bd);
                }
            }
            var rows = grid.RowDefinitions.Count;
            var cols = grid.ColumnDefinitions.Count;
            //邊界考慮
            if (rows == 0)
            {
                rows = 1;
            }
            if (cols == 0)
            {
                cols = 1;
            }
            //生成行列
            for (var i = 0; i < rows; i++)
            {
                for (var j = 0; j < cols; j++)
                {
                    var thick = new Thickness(lineWidth, lineWidth, 0, 0);
                    var margin = new Thickness(-lineWidth/2d, -lineWidth/2d, 0, 0);
                    //邊界考慮 
                    if (i == 0)
                    {
                        margin.Top = 0;
                    }
                    if (i == rows - 1)
                    {
                        thick.Bottom = lineWidth;
                    }
                    if (j == 0)
                    {
                        margin.Left = 0;
                    }
                    if (j == cols - 1)
                    {
                        thick.Right = lineWidth;
                    }
                    var bd = new Border
                    {
                        BorderThickness = thick,
                        Margin = margin,
                        BorderBrush = color,
                        Tag = "gridline"
                    };
                    Grid.SetRow(bd, i);
                    Grid.SetColumn(bd, j);
                    grid.Children.Add(bd);
                }
            }
            grid.InvalidateArrange();
            grid.InvalidateVisual();
        }

        #region 線顏色

        // Using a DependencyProperty as the backing store for LineColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LineColorProperty =
            DependencyProperty.RegisterAttached("LineColor", typeof (Brush), typeof (GridHelper),
                new PropertyMetadata(Brushes.Black, LineColorPropertyChanged));

        public static Brush GetLineColor(DependencyObject obj)
        {
            return (Brush) obj.GetValue(LineColorProperty);
        }

        public static void SetLineColor(DependencyObject obj, Brush value)
        {
            obj.SetValue(LineColorProperty, value);
        }


        private static void LineColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var grid = d as Grid;
            if (grid == null)
            {
                return;
            }
            var showLines = GetShowGridLines(grid);
            var color = GetLineColor(grid);
            var lineWidth = GetLineWidth(grid);
            if (showLines)
            {
                //  grid.SnapsToDevicePixels = true;
                grid.Loaded += delegate { RefreshGrid(grid, lineWidth, color); };
            }
        }

        #endregion

        #region 線寬度

        // Using a DependencyProperty as the backing store for LineWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LineWidthProperty =
            DependencyProperty.RegisterAttached("LineWidth", typeof (int), typeof (GridHelper),
                new PropertyMetadata(1, LineWidthPropertyChanged));

        public static int GetLineWidth(DependencyObject obj)
        {
            return (int) obj.GetValue(LineWidthProperty)
                ;
        }


        public static void SetLineWidth(DependencyObject obj, int value)
        {
            obj.SetValue(LineWidthProperty, value);
        }


        private static void LineWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var grid = d as Grid;
            if (grid == null)
            {
                return;
            }
            var showLines = GetShowGridLines(grid);
            var color = GetLineColor(grid);
            var lineWidth = GetLineWidth(grid);
            if (showLines)
            {
                // grid.SnapsToDevicePixels = true;
                grid.Loaded += delegate { RefreshGrid(grid, lineWidth, color); };
            }
        }

        #endregion

        #region 是否顯示線

        // Using a DependencyProperty as the backing store for ShowGridLines.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ShowGridLinesProperty =
            DependencyProperty.RegisterAttached("ShowGridLines", typeof (bool), typeof (GridHelper),
                new PropertyMetadata(false, ShowGridLinesPropertyChanged));


        public static bool GetShowGridLines(DependencyObject obj)
        {
            return (bool) obj.GetValue(ShowGridLinesProperty);
        }

        public static void SetShowGridLines(DependencyObject obj, bool value)
        {
            obj.SetValue(ShowGridLinesProperty, value);
        }


        private static void ShowGridLinesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var grid = d as Grid;
            if (grid == null)
            {
                return;
            }
            var showLines = GetShowGridLines(grid);
            var color = GetLineColor(grid);
            var lineWidth = GetLineWidth(grid);
            if (showLines)
            {
                //  grid.SnapsToDevicePixels = true;
                grid.Loaded += delegate { RefreshGrid(grid, lineWidth, color); };
            }
        }

        #endregion
    }
}

  

2.效果圖

效果還可以,任何分辨率下,任何邊框大小,都沒有出現像素對齊或者模糊問題。 圖中的虛線是grid的默認gridLine,紅色和綠色是自定義的gridline,跟虛線完美重合。

 

 

3.源碼下載

https://files.cnblogs.com/files/chlm/%E7%94%A8%E9%99%84%E5%8A%A0%E5%B1%9E%E6%80%A7%E4%BF%AE%E6%94%B9Grid%E7%9A%84%E8%BE%B9%E6%A1%86.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM