WPF Border實現九宮格背景畫刷
阿新 • • 發佈:2018-12-17
Xaml
<customcontrol:NineGridBorder
ImageMargin="2,2,2,8"
Image="/xxxxx;component/Images/xxxx.png">
<Grid>
</Grid>
</customcontrol:NineGridBorder>
後臺
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace CustomControl { /// <summary> /// 九宮格背景Border /// </summary> public class NineGridBorder : Border { /// <summary> /// 圖片源 /// </summary> public ImageSource Image { get { return (ImageSource)base.GetValue(ImageProperty); } set { base.SetValue(ImageProperty, value); } } /// <summary> /// 圖片源 /// </summary> public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(NineGridBorder), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 圖片四個邊距 /// </summary> public Thickness ImageMargin { get { return (Thickness)GetValue(ImageMarginProperty); } set { SetValue(ImageMarginProperty, value); } } /// <summary> /// 圖片四個邊距 /// </summary> public static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register("ImageMargin", typeof(Thickness), typeof(NineGridBorder), new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 圖片透明度 /// </summary> public double ImageOpacity { get { return (double)GetValue(ImageOpacityProperty); } set { SetValue(ImageOpacityProperty, value); } } /// <summary> /// 圖片透明度 /// </summary> public static readonly DependencyProperty ImageOpacityProperty = DependencyProperty.Register("ImageOpacity", typeof(double), typeof(NineGridBorder), new FrameworkPropertyMetadata(1D, FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary> /// 是否九宮格方式 /// </summary> private bool IsNineGrid { get { return !ImageMargin.Equals(new Thickness()); } } protected override void OnRender(DrawingContext dc) { DrawImage(dc, new Rect(0, 0, RenderSize.Width, RenderSize.Height)); } private void DrawImage(DrawingContext dc, Rect rect) { ImageSource source = Image; if (source != null) { double opacity = ImageOpacity; if (IsNineGrid) { Thickness margin = Clamp(ImageMargin, new Size(source.Width, source.Height), rect.Size); double[] xGuidelines = { 0, margin.Left, rect.Width - margin.Right, rect.Width }; double[] yGuidelines = { 0, margin.Top, rect.Height - margin.Bottom, rect.Height }; GuidelineSet guidelineSet = new GuidelineSet(xGuidelines, yGuidelines); guidelineSet.Freeze(); dc.PushGuidelineSet(guidelineSet); double[] vx = { 0D, margin.Left / source.Width, (source.Width - margin.Right) / source.Width, 1D }; double[] vy = { 0D, margin.Top / source.Height, (source.Height - margin.Bottom) / source.Height, 1D }; double[] x = { rect.Left, rect.Left + margin.Left, rect.Right - margin.Right, rect.Right }; double[] y = { rect.Top, rect.Top + margin.Top, rect.Bottom - margin.Bottom, rect.Bottom }; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { ImageBrush brush = new ImageBrush(source); brush.Opacity = opacity; brush.Viewbox = new Rect(vx[j], vy[i], Math.Max(0D, (vx[j + 1] - vx[j])), Math.Max(0D, (vy[i + 1] - vy[i]))); dc.DrawRectangle(brush, null, new Rect(x[j], y[i], Math.Max(0D, (x[j + 1] - x[j])), Math.Max(0D, (y[i + 1] - y[i])))); } } dc.Pop(); } else { ImageBrush brush = new ImageBrush(source); brush.Opacity = opacity; dc.DrawRectangle(brush, null, rect); } } } private static Thickness Clamp(Thickness margin, Size firstMax, Size secondMax) { double left = Clamp(margin.Left, firstMax.Width, secondMax.Width); double top = Clamp(margin.Top, firstMax.Height, secondMax.Height); double right = Clamp(margin.Right, firstMax.Width - left, secondMax.Width - left); double bottom = Clamp(margin.Bottom, firstMax.Height - top, secondMax.Height - top); return new Thickness(left, top, right, bottom); } private static double Clamp(double value, double firstMax, double secondMax) { return Math.Max(0, Math.Min(Math.Min(value, firstMax), secondMax)); } } }