• 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>
  • 相关阅读:
    拓端tecdat|R语言平滑算法LOESS局部加权回归、三次样条、变化点检测拟合电视节目《白宫风云》在线收视率
    拓端tecdat|R语言结合新冠疫情COVID-19对股票价格预测:ARIMA,KNN和神经网络时间序列分析
    拓端tecdat|Stata广义矩量法GMM面板向量自回归PVAR模型选择、估计、Granger因果检验分析投资、收入和消费数据
    拓端tecdat|Python用T-SNE非线性降维技术拟合和可视化高维数据iris鸢尾花、MNIST 数据
    confirmit中常用 短代码
    DELL服务器硬件信息采集SHELL脚本
    功能、资源权限管理的设计
    maven--插件篇(assembly插件)
    呀哈哈
    virtualbox扩展硬盘容量
  • 原文地址:https://www.cnblogs.com/xmax130/p/4035142.html
Copyright © 2020-2023  润新知