使用了不少网络的九宫格画法,多多少少存在问题,这里将其改进
使用方法:
<local:NineGridBorder
<!--代表距离四周的间距-->
ImageMargin="10,109,10,68"
<!--图片原始尺寸-->
ImageSize="1360, 725"
<!--图片-->
Image="pack://application:,,,/XXX/XXX.png">
<Canvas>
</Canvas>
</customcontrol:NineGridBorder>
具体类:
/// <summary>
/// 九宫格背景Border
/// </summary>
public class NineGridBorder : Border
{
public Size ImageSize
{
get { return (Size)base.GetValue(ImageSizeProperty); }
set { base.SetValue(ImageSizeProperty, value); }
}
/// <summary>
/// 图片原始尺寸
/// </summary>
public static readonly DependencyProperty ImageSizeProperty = DependencyProperty.Register("ImageSize",
typeof(Size), typeof(NineGridBorder),
new FrameworkPropertyMetadata(new Size(), FrameworkPropertyMetadataOptions.AffectsRender));
/// <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[] 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 };
double[] lx = { 0, margin.Left, ImageSize.Width - margin.Right, ImageSize.Width };
double[] ly = { 0, margin.Top, ImageSize.Height - margin.Bottom, ImageSize.Height };
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
dc.DrawRectangle(new ImageBrush(new CroppedBitmap((BitmapSource)source, new Int32Rect((int)lx[j], (int)ly[i], (int)(lx[j + 1] - lx[j]), (int)(ly[i + 1] - ly[i])))), 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));
}
}