WPF使用四边不同颜色的Border

正常情况下WPF自带的Border都能满足我们日常使用。但某些情况下遇到比较复杂的需求时候原生的效果还是不能满足我们的需求。例如以下这种立体边框:

当然如果这种尺寸是固定的,我们只需要美工提供图片就可以了,但如果尺寸是可以动态变动的我们就不能使用图片作为背景了,因为背景边框也是会拉伸的,谁叫咋们的WPF不能像IOS开发那样设置一个值边框就不会拉伸·······

好吧,我们只有自己动手实现一个四个边框不同颜色的border来实现了。

1.首先,我们创建一个类,继承自Borde。再新建4个边框的Brush依赖属性保存用户设置的四个Brush。

        public Brush LeftBorderBrush
        {
            get { return (Brush)GetValue(LeftBorderBrushProperty); }
            set { SetValue(LeftBorderBrushProperty, value); }
        }

        public static readonly DependencyProperty LeftBorderBrushProperty =
            DependencyProperty.Register("LeftBorderBrush", typeof(Brush), typeof(FouerColorBorder), new PropertyMetadata(null));

        public Brush TopBorderBrush
        {
            get { return (Brush)GetValue(TopBorderBrushProperty); }
            set { SetValue(TopBorderBrushProperty, value); }
        }

        public static readonly DependencyProperty TopBorderBrushProperty =
            DependencyProperty.Register("TopBorderBrush", typeof(Brush), typeof(FouerColorBorder), new PropertyMetadata(null));

        public Brush RightBorderBrush
        {
            get { return (Brush)GetValue(RightBorderBrushProperty); }
            set { SetValue(RightBorderBrushProperty, value); }
        }

        public static readonly DependencyProperty RightBorderBrushProperty =
            DependencyProperty.Register("RightBorderBrush", typeof(Brush), typeof(FouerColorBorder), new PropertyMetadata(null));

        public Brush BottomBorderBrush
        {
            get { return (Brush)GetValue(BottomBorderBrushProperty); }
            set { SetValue(BottomBorderBrushProperty, value); }
        }

        public static readonly DependencyProperty BottomBorderBrushProperty =
            DependencyProperty.Register("BottomBorderBrush", typeof(Brush), typeof(FouerColorBorder), new PropertyMetadata(null));

2.接着我们得重写OnRender方法。

        protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {

            base.OnRender(dc);
            bool useLayoutRounding = base.UseLayoutRounding;

                Thickness borderThickness = this.BorderThickness;
                CornerRadius cornerRadius = this.CornerRadius;
                double topLeft = cornerRadius.TopLeft;
                bool flag = !DoubleUtil.IsZero(topLeft);
                Brush borderBrush=null;

                    Pen pen=null;
                    if (pen == null)
                    {
                        pen = new Pen();
                        borderBrush = LeftBorderBrush;
                        pen.Brush = LeftBorderBrush;
                        if (useLayoutRounding)
                        {
                            pen.Thickness = UlementEx.RoundLayoutValue(borderThickness.Left, DoubleUtil.DpiScaleX);
                        }
                        else
                        {
                            pen.Thickness = borderThickness.Left;
                        }
                        if (borderBrush != null)
                        {
                            if (borderBrush.IsFrozen)
                            {
                                pen.Freeze();
                            }
                        }

                        if (DoubleUtil.GreaterThan(borderThickness.Left, 0.0))
                        {
                            double num = pen.Thickness * 0.5;
                            dc.DrawLine(pen, new Point(num, 0.0), new Point(num, base.RenderSize.Height));
                        }
                        if (DoubleUtil.GreaterThan(borderThickness.Right, 0.0))
                        {

                                pen = new Pen();
                                pen.Brush = RightBorderBrush;
                                if (useLayoutRounding)
                                {
                                    pen.Thickness = UlementEx.RoundLayoutValue(borderThickness.Right, DoubleUtil.DpiScaleX);
                                }
                                else
                                {
                                    pen.Thickness = borderThickness.Right;
                                }
                                if (borderBrush != null)
                                {
                                    if (borderBrush.IsFrozen)
                                    {
                                        pen.Freeze();
                                    }
                                }

                            double num = pen.Thickness * 0.5;
                            dc.DrawLine(pen, new Point(base.RenderSize.Width - num, 0.0), new Point(base.RenderSize.Width - num, base.RenderSize.Height));
                        }
                        if (DoubleUtil.GreaterThan(borderThickness.Top, 0.0))
                        {

                                pen = new Pen();
                                pen.Brush = TopBorderBrush;
                                if (useLayoutRounding)
                                {
                                    pen.Thickness = UlementEx.RoundLayoutValue(borderThickness.Top, DoubleUtil.DpiScaleY);
                                }
                                else
                                {
                                    pen.Thickness = borderThickness.Top;
                                }
                                if (borderBrush != null)
                                {
                                    if (borderBrush.IsFrozen)
                                    {
                                        pen.Freeze();
                                    }
                                }

                            double num = pen.Thickness * 0.5;
                            dc.DrawLine(pen, new Point(0.0, num), new Point(base.RenderSize.Width, num));
                        }
                        if (DoubleUtil.GreaterThan(borderThickness.Bottom, 0.0))
                        {

                                pen = new Pen();
                                pen.Brush = BottomBorderBrush;
                                if (useLayoutRounding)
                                {
                                    pen.Thickness = UlementEx.RoundLayoutValue(borderThickness.Bottom, DoubleUtil.DpiScaleY);
                                }
                                else
                                {
                                    pen.Thickness = borderThickness.Bottom;
                                }
                                if (borderBrush != null)
                                {
                                    if (borderBrush.IsFrozen)
                                    {
                                        pen.Freeze();
                                    }
                                }

                            double num = pen.Thickness * 0.5;
                            dc.DrawLine(pen, new Point(0.0, base.RenderSize.Height - num), new Point(base.RenderSize.Width, base.RenderSize.Height - num));
                        }

            }

3.在写这个方法前,我们得新建一个DoubleUtil类来计算相关的值。这个类是。net自带的,但提供的方法权限是internal的,所以我们不能访问,这里我提供和系统一样的方法,尽管调用就可以了。

 public  class DoubleUtil
    {

      public static double DpiScaleX
      {
          get
          {
              int dx = 0;
              int dy = 0;
              GetDPI(out dx,out dy);
              if (dx != 96)
              {
                  return (double)dx / 96.0;
              }
              return 1.0;
          }
      }

      public static double DpiScaleY
      {
          get
          {
              int dx = 0;
              int dy = 0;
              GetDPI(out dx, out dy);
              if (dy != 96)
              {
                  return (double)dy / 96.0;
              }
              return 1.0;
          }
      }

      public static void GetDPI(out int dpix, out int dpiy)
      {
          dpix = 0;
          dpiy = 0;
          using (System.Management.ManagementClass mc = new System.Management.ManagementClass("Win32_DesktopMonitor"))
          {
              using (System.Management.ManagementObjectCollection moc = mc.GetInstances())
              {

                  foreach (System.Management.ManagementObject each in moc)
                  {
                      dpix = int.Parse((each.Properties["PixelsPerXLogicalInch"].Value.ToString()));
                      dpiy = int.Parse((each.Properties["PixelsPerYLogicalInch"].Value.ToString()));
                  }
              }
          }
      }
        public static bool GreaterThan(double value1, double value2)
        {
            return value1 > value2 && !DoubleUtil.AreClose(value1, value2);
        }

        public static bool AreClose(double value1, double value2)
        {
            if (value1 == value2)
            {
                return true;
            }
            double num = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * 2.2204460492503131E-16;
            double num2 = value1 - value2;
            return -num < num2 && num > num2;
        }

        public static bool IsZero(double value)
        {
            return Math.Abs(value) < 2.2204460492503131E-15;
        }

        [StructLayout(LayoutKind.Explicit)]
        private struct NanUnion
        {
            [FieldOffset(0)]
            internal double DoubleValue;
            [FieldOffset(0)]
            internal ulong UintValue;
        }

        public static bool IsNaN(double value)
        {
            DoubleUtil.NanUnion nanUnion = default(DoubleUtil.NanUnion);
            nanUnion.DoubleValue = value;
            ulong num = nanUnion.UintValue & 18442240474082181120uL;
            ulong num2 = nanUnion.UintValue & 4503599627370495uL;
            return (num == 9218868437227405312uL || num == 18442240474082181120uL) && num2 != 0uL;
        }

    }

  public static class UlementEx
  {
     public static double RoundLayoutValue(double value, double dpiScale)
      {
          double num;
          if (!DoubleUtil.AreClose(dpiScale, 1.0))
          {
              num = Math.Round(value * dpiScale) / dpiScale;
              if (DoubleUtil.IsNaN(num) || double.IsInfinity(num) || DoubleUtil.AreClose(num, 1.7976931348623157E+308))
              {
                  num = value;
              }
          }
          else
          {
              num = Math.Round(value);
          }
          return num;
      }
  }

4.最后在xaml界面这样使用就可以了:

<localCtrl:FouerColorBorder  x:Name="LeftBorder" RightBorderBrush="#595e61"   BottomBorderBrush="#595e61" BorderThickness="0,0,0.7,0.7"></localCtrl:FouerColorBorder>
时间: 2024-10-09 08:38:29

WPF使用四边不同颜色的Border的相关文章

WPF学习:3.Border &amp; Brush

上一章<WPF学习:2.Layout-Panels-Countainers>主要介绍了布局,容器和面板.这一章主要开始介绍Border(边界)和Brush(画刷). 代码地址:http://www.cnblogs.com/keylei203/archive/2013/03/12/keylei203.html 引言 在任何WPF的程序设计中,Border都占主要部分,一般都会使用很多Border装饰用户界面.从直接在window上放置borders到在ListBoxItem上放置Borders,

css学习之border 边框

边框,也就是盒子模型的四周, 1.四边相同边框border简写#divcss5{border:1px solid #00F} CSS读取有从上到下.从左到右读取原理,而先设置了整个边框样式,后再加上声明顶部上边边框为“none”

CSS border边框取值

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <st

CSS border边框属性教程(color style)

CSS 边框即CSS border-border边框样式颜色.边框样式.边框宽度的语法结构与应用案例教程篇 一.CSS 边框基础知识 CSS 边框即CSS border是控制对象的边框边线宽度.颜色.虚线.实线等样式CSS属性.同时大家可以进入码农教程提供CSS手册查看border手册:http://www.manongjc.com/cssref/pr_border.html 二.Html原始边框与DIV+CSS边框对照 Html表格控制边框:border="1" bordercolo

Css之border属性

设置border属性作用:设置对象边框样式,设置单独上边框.下边框.左边框.右边框样式,实现美化美观.边框起到分割.规划布局作用. 1.四个边框 border-left 设置左边框,一般单独设置左边框样式使用border-right 设置右边框,一般单独设置右边框样式使用border-top 设置上边框,一般单独设置上边框样式使用border-bottom 设置下边框,一般单独设置下边框样式使用,有时可将下边框样式作为css下划线效果应用. 2.四边相同边框border简写#divcss5{bo

border、margin、padding三者的区别

当你写前端的时候,肯定会遇到border,margin和padding这几个单词. 如: padding: 16px 0; margin: 0 10px; 在CSS中,他们是表示距离的东西,很多人刚开始搞不清楚他们的区别,我也是.在网上找到一个很好的说明他们之间的区别的示意图,border.margin.padding三者的区别. 边框属性(border)用来设定一个元素的边线. 边距属性(margin)是用来设置一个元素所占空间的边缘到相邻元素之间的距离. 间隙属性(padding)是用来设置

WPF应用中对WindowsFormHost内容进行裁剪

问题1:  WPF中在使用WindowsFormsHost调用WinFrom控件时,若在WindowsFormsHost上层添加了WPF控件,该控件不会显示出来. <Grid> <WindowsFormsHost Background="White"> <Winfrm:WebBrowser x:Name="WinFrmWebBrowser"/> </WindowsFormsHost> <!--运行时 Ellips

制作自定义样式的窗口

不使用windows自带的窗口样式,使用自定义的客户区, <Window xmlns:my="clr-namespace:MiniFileTransferClient.Presentation.WPF.UILogic.ShowPanels" x:Class="MiniFileTransferClient.Presentation.WPF.MiniFileTransferViewer" xmlns="http://schemas.microsoft.c

WEB CSS

一.CSS CSS有三种用法:内联样式:内部样式:外部样式 二.CSS语法规范 CSS由多个样式规则组成,每个样式规则有两个部分:选择器和样式声明 eg: h1 {color:red; font-size:14px;} 这里的h1为选择器,color:red为一组声明key:value 三.CSS规则特性 1.继承性 父元素的CSS声明可以被子元素继承,如字体颜色等. 2.层叠性 同一个元素若存在多个css规则,对于不冲突的声明可以叠加. 3.优先级 同一个元素若存在多个css规则,对于冲突的声