WPF如何利用附加屬性修改ShowGridLines效果詳解
前言
附加屬性是說(shuō)一個(gè)屬性本來(lái)不屬于某個(gè)對(duì)象,但由于某種需求而被后來(lái)附加上,也就是把對(duì)象放入一個(gè)特定環(huán)境后對(duì)象才具有的屬性就稱(chēng)為附加屬性,附加屬性的作用就是將屬性與數(shù)據(jù)類(lèi)型解耦,讓數(shù)據(jù)類(lèi)型的設(shè)計(jì)更加靈活,舉例,一個(gè)TextBox被放在不同的布局容器中時(shí)就會(huì)有不同的布局屬性,這些屬性就是由布局容器為T(mén)extBox附加上的,附加屬性的本質(zhì)就是依賴(lài)屬性,二者僅僅在注冊(cè)和包裝器上有一點(diǎn)區(qū)別
小技巧,在VS中輸入propa后,連按兩次tab鍵,可以添加好一個(gè)附加屬性的框架,繼續(xù)按tab鍵,可以繼續(xù)修改附加屬性的內(nèi)容
本文主要介紹的是關(guān)于WPF用附加屬性修改ShowGridLines效果的相關(guān)內(nèi)容,下面話(huà)不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
1.思路主要代碼
wpf的gridline原本效果是虛線(xiàn)類(lèi)型的。有時(shí)候需要設(shè)計(jì)成表格形式的,因此有了用附加屬性來(lái)自動(dòng)繪制邊框線(xiàn)的想法。
思路:繪制Line并添加到grid的children里,但效果并不理想,會(huì)出現(xiàn)鋸齒,像素對(duì)齊,模糊等問(wèn)題。
UseLayoutRounding="False"
SnapsToDevicePixels="True"
RenderOptions.EdgeModeProperty 貌似都沒(méi)起作用。
于是想到了用border來(lái)實(shí)現(xiàn),簡(jiǎn)單又實(shí)用吧 哈哈。
大致思路如下:
繪制border的左邊框和上邊框,在邊界的時(shí)候考慮邊界封閉。然后將border平移一半的距離。這樣邊框就居中并且包圍了所有的線(xiàn)。

主要代碼如下:
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 線(xiàn)顏色
// 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 線(xiàn)寬度
// 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 是否顯示線(xiàn)
// 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.效果圖
效果還可以,任何分辨率下,任何邊框大小,都沒(méi)有出現(xiàn)像素對(duì)齊或者模糊問(wèn)題。 圖中的虛線(xiàn)是grid的默認(rèn)gridLine,紅色和綠色是自定義的gridline,跟虛線(xiàn)完美重合。
3.源碼下載
下載地址:http://xiazai.jb51.net/201804/yuanma/WPF-fujia-ShowGridLines(jb51.net).rar
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
C#對(duì)DataTable中的某列進(jìn)行分組
這篇文章介紹了C#對(duì)DataTable某列進(jìn)行分組的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
Unity實(shí)現(xiàn)游戲傷害數(shù)字顯示HUD的方法
游戲中收到傷害掉血,會(huì)有飄動(dòng)的傷害數(shù)值,本文主要介紹Unity實(shí)現(xiàn)游戲傷害數(shù)字顯示HUD的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C#實(shí)現(xiàn)簡(jiǎn)單的3DES加密解密功能示例
這篇文章主要介紹了C#實(shí)現(xiàn)簡(jiǎn)單的3DES加密解密功能,結(jié)合實(shí)例形式分析了C#實(shí)現(xiàn)3DES加密解密的定義、使用等具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
C#編程獲取客戶(hù)端計(jì)算機(jī)硬件及系統(tǒng)信息功能示例
這篇文章主要介紹了C#編程獲取客戶(hù)端計(jì)算機(jī)硬件及系統(tǒng)信息功能,可實(shí)現(xiàn)針對(duì)客戶(hù)端系統(tǒng)CPU、硬盤(pán)、主板等硬件信息及客戶(hù)端操作系統(tǒng)、IP、MAC等信息的操作技巧,需要的朋友可以參考下2017-01-01
VS2019下安裝和破解?DevExpress?19.2?插件的詳細(xì)教程
這篇文章主要介紹了VS2019?安裝并破解?DevExpress?19.2?插件的詳細(xì)教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
深入學(xué)習(xí)C#網(wǎng)絡(luò)編程之HTTP應(yīng)用編程(下)
這篇文章主要介紹了深入學(xué)習(xí)C#網(wǎng)絡(luò)編程之HTTP應(yīng)用編程的相關(guān)知識(shí),文中講解的非常詳細(xì),幫助大家更好的學(xué)習(xí)c#網(wǎng)絡(luò)編程,感興趣的朋友可以了解下2020-06-06
C#中的應(yīng)用程序接口介紹及實(shí)現(xiàn),密封類(lèi)與密封方法
今天小編就為大家分享一篇關(guān)于C#中的應(yīng)用程序接口介紹及實(shí)現(xiàn),密封類(lèi)與密封方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
C#實(shí)現(xiàn)一個(gè)控制臺(tái)的點(diǎn)餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)一個(gè)控制臺(tái)的點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
C#代替go采用的CSP并發(fā)模型實(shí)現(xiàn)
這篇文章主要為大家介紹了C#代替go采用的CSP并發(fā)模型的輕松實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

