zoukankan      html  css  js  c++  java
  • 分享:动态添加控件和公用章水印工具 提供源码下载

      动态添加控件

       需求:最近项目有个小功能,根据配置文件配置的个数,动态在窗体上生成指定个数的TextBox,并获取其内容用于业务需求。

           无废话,直接上核心代码:

           

            /// <summary>
            /// 获取所有TextBox的内容
            /// </summary>
            private void GetAllTextBoxValue()
            {
                StringBuilder sb = new StringBuilder();
                foreach (Control c in this.PanelCarton.Controls)
                {
                    if (c is TextBox)
                    {
                        TextBox testBox = c as TextBox;
                        sb.Append(testBox.Text+",");
                    }
                } 
                 label1.Text = sb.ToString();
            }
    
            /// <summary>
            ///根据配置的units,动态添加TextBox控件
            /// </summary>
            /// <param name="units"></param>
            private void AddTextBoxControlByUnits(int units)
            {
                int loopCount = 0;
                int txtID = 0;
                int x = units, y = 5;
                while (x > y)
                {
                    for (int j = 1; j <= y; j++)
                    {
                        TextBox textBox = new TextBox();
                        //textBox.Name = string.Format("txtSN{0}", (x-y)*j+1);
                        textBox.Name = string.Format("txtSN{0}", txtID);
                        textBox.Width = 200;
                        textBox.Height = 20;
                        textBox.BorderStyle = BorderStyle.FixedSingle;
                        textBox.Location = new Point(10 + 250 * loopCount, 10 + (j - 1) * 65);
                       //textBox.Text = txtID.ToString();//用于定位,下同
                        PanelCarton.Controls.Add(textBox);
                        txtID++;
                    }
                    x -= y;
                    ++loopCount;
                }
                int leftOffset = 10 + 250 * loopCount;
                for (int j = 1; j <= x; j++)
                {
                    TextBox textBox = new TextBox();
                    //textBox.Name = string.Format("txtSN{0}", j-1);
                    textBox.Name = string.Format("txtSN{0}",txtID);
                    textBox.Width = 200;
                    textBox.Height = 20;
                    textBox.BorderStyle = BorderStyle.FixedSingle;
                    textBox.Location = new Point(leftOffset, 10 + (j - 1) * 65);
                    //textBox.Text = txtID.ToString();
                    PanelCarton.Controls.Add(textBox);
                    txtID++;
                } 
            }

         以上代码比较简单,但也做个简单的介绍:

         AddTextBoxControlByUnits方法:核心在于处理“被整除”和“没有被整除”。举个简单例子。比如配置文件需要显示10个TextBox, 10÷5=2能被整除,所以在while循环处循环2次,每次循环创建5个TextBox。 最下面的for循环水用于处理不能被5整除的情况。比如需要生成12给TextBox,12÷5=2 余2,所以最下面的for循环就是用来干这事的。循环余下的2次循环。 
         GetAllTextBoxValue()方法:用于获取上述方法动态生成的TextBox的内容。太简单,不做分析

        (对于文中处理方法,如果大家有更高效,更简单的方法,希望大家不吝赐教~ 再次谢过)

         具体效果如下:

         

          

      公用章水印工具

       通过上面的效果图,大家可以看到图片的右下角有个公用章的水印。

        无废话,直接上核心代码:

        

      /// <summary>
            /// Compute string total length and every char length
            /// </summary>
            /// <param name="sText"></param>
            /// <param name="g"></param>
            /// <param name="fCharWidth"></param>
            /// <param name="fIntervalWidth"></param>
            /// <returns></returns>
            private float ComputeStringLength(string sText, Graphics g, float[] fCharWidth,
                float fIntervalWidth,
                Char_Direction Direction)
            {
                // Init string format
                StringFormat sf = new StringFormat();
                sf.Trimming = StringTrimming.None;
                sf.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap
                    | StringFormatFlags.LineLimit;
    
                // Measure whole string length
                SizeF size = g.MeasureString(sText, _font, (int)_font.Style);
                RectangleF rect = new RectangleF(0f, 0f, size.Width, size.Height);
    
                // Measure every character size
                CharacterRange[] crs = new CharacterRange[sText.Length];
                for (int i = 0; i < sText.Length; i++)
                    crs[i] = new CharacterRange(i, 1);
    
                // Reset string format
                sf.FormatFlags = StringFormatFlags.NoClip;
                sf.SetMeasurableCharacterRanges(crs);
                sf.Alignment = StringAlignment.Near;
    
                // Get every character size
                Region[] regs = g.MeasureCharacterRanges(sText,
                    _font, rect, sf);
    
                // Re-compute whole string length with space interval width
                float fTotalWidth = 0f;
                for (int i = 0; i < regs.Length; i++)
                {
                    if (Direction == Char_Direction.Center || Direction == Char_Direction.OutSide)
                        fCharWidth[i] = regs[i].GetBounds(g).Width;
                    else
                        fCharWidth[i] = regs[i].GetBounds(g).Height;
                    fTotalWidth += fCharWidth[i] + fIntervalWidth;
                }
                fTotalWidth -= fIntervalWidth;//Remove the last interval width
    
                return fTotalWidth;
    
            }
    
            /// <summary>
            /// Compute every char position
            /// </summary>
            /// <param name="CharWidth"></param>
            /// <param name="recChars"></param>
            /// <param name="CharAngle"></param>
            /// <param name="StartAngle"></param>
            private void ComputeCharPos(
                float[] CharWidth,
                PointF[] recChars,
                double[] CharAngle,
                double StartAngle)
            {
                double fSweepAngle, fCircleLength;
                //Compute the circumference
                fCircleLength = _rectcircle.Width * Math.PI;
    
                for (int i = 0; i < CharWidth.Length; i++)
                {
                    //Get char sweep angle
                    fSweepAngle = CharWidth[i] * 360 / fCircleLength;
    
                    //Set point angle
                    CharAngle[i] = StartAngle + fSweepAngle / 2;
    
                    //Get char position
                    if (CharAngle[i] < 270f)
                        recChars[i] = new PointF(
                            _rectcircle.X + _rectcircle.Width / 2
                            - (float)(_rectcircle.Width / 2 *
                            Math.Sin(Math.Abs(CharAngle[i] - 270) * Math.PI / 180)),
                            _rectcircle.Y + _rectcircle.Width / 2
                            - (float)(_rectcircle.Width / 2 * Math.Cos(
                            Math.Abs(CharAngle[i] - 270) * Math.PI / 180)));
                    else
                        recChars[i] = new PointF(
                            _rectcircle.X + _rectcircle.Width / 2
                            + (float)(_rectcircle.Width / 2 *
                            Math.Sin(Math.Abs(CharAngle[i] - 270) * Math.PI / 180)),
                            _rectcircle.Y + _rectcircle.Width / 2
                            - (float)(_rectcircle.Width / 2 * Math.Cos(
                            Math.Abs(CharAngle[i] - 270) * Math.PI / 180)));
    
                    //Get total sweep angle with interval space
                    fSweepAngle = (CharWidth[i] + _letterspace) * 360 / fCircleLength;
                    StartAngle += fSweepAngle;
    
                }
            }
    
            /// <summary>
            /// Generate seal bitmap
            /// </summary>
            /// <returns></returns>
            public Bitmap TextOnPathBitmap()
            {
                // Create bitmap and graphics
                Bitmap bit = new Bitmap(_rect.Width, _rect.Height);
                Graphics g = Graphics.FromImage(bit);
    
                // Compute string length in graphics
                float[] fCharWidth = new float[_text.Length];
                float fTotalWidth = ComputeStringLength(_text, g, fCharWidth,
                    _letterspace, _chardirect);
    
                // Compute arc's start-angle and end-angle
                double fStartAngle, fSweepAngle;
                fSweepAngle = fTotalWidth * 360 / (_rectcircle.Width * Math.PI);
                fStartAngle = 270 - fSweepAngle / 2;
    
                // Compute every character's position and angle
                PointF[] pntChars = new PointF[_text.Length];
                double[] fCharAngle = new double[_text.Length];
                ComputeCharPos(fCharWidth, pntChars, fCharAngle, fStartAngle);
    
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    
                DrawSealBase(g);
    
                // Draw every character
                for (int i = 0; i < _text.Length; i++)
                    DrawRotatedText(g, _text[i].ToString(), (float)(fCharAngle[i] + _degree), pntChars[i]);
    
                g.Dispose();
    
                // Return bitmap
                return bit;
            }
    
            /// <summary>
            /// Draw seal base 
            /// </summary>
            /// <param name="g"></param>
            private void DrawSealBase(Graphics g)
            {
                // Draw background
                g.FillRectangle(Brushes.Transparent, _rect);
                #region 填充圆内部颜色
                //g.FillEllipse(new SolidBrush(_fillcolor),
                //    new Rectangle(1, 1, _rect.Width - 2, _rect.Height - 2));
                //g.FillEllipse(Brushes.Black,
                //    new Rectangle(4, 4, _rect.Width - 8, _rect.Height - 8)); 
                #endregion
                //画个空心圆(自我感觉这样效果比较好,如果想用喜欢的颜色填充可以用上面屏蔽掉的代码)
                g.DrawEllipse(new Pen(Brushes.Red,3), new Rectangle(4, 4, _rect.Width - 8, _rect.Height - 8));
    
                // Draw start signal
                StringFormat sf = new StringFormat();
                string strStar = "";
                Font fnt = new Font(_font.FontFamily, _font.Size * 3);
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                SizeF siz = g.MeasureString(strStar, fnt);
                g.DrawString(strStar, fnt, new SolidBrush(_fillcolor),
                    new RectangleF(_rect.Width / 2 - siz.Width / 2,
                    _rect.Height / 2 - siz.Height / 2,
                    siz.Width, siz.Height), sf);
    
                // Draw base string
                float[] fCharWidth = new float[_basestring.Length];
                float fTotalWidths = ComputeStringLength(_basestring, g, fCharWidth, 0,
                    Char_Direction.Center);
                float fLeftPos = (_rect.Width - fTotalWidths) / 2;
                PointF pt;
                for (int i = 0; i < _basestring.Length; i++)
                {
                    pt = new PointF(fLeftPos + fCharWidth[i] / 2,
                        _rect.Height / 2 + siz.Height / 2 + 10);
                    DrawRotatedText(g, _basestring[i].ToString(), 0, pt);
                    fLeftPos += fCharWidth[i];
                }
            }
    
            /// <summary>
            /// Draw every rotated character
            /// </summary>
            /// <param name="g"></param>
            /// <param name="_text"></param>
            /// <param name="_angle"></param>
            /// <param name="_PointCenter"></param>
            private void DrawRotatedText(Graphics g, string _text, float _angle, PointF _PointCenter)
            {
                // Init format
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
    
                // Create graphics path
                GraphicsPath gp = new GraphicsPath(System.Drawing.Drawing2D.FillMode.Winding);
                int x = (int)_PointCenter.X;
                int y = (int)_PointCenter.Y;
    
                // Add string
                gp.AddString(_text, _font.FontFamily, (int)_font.Style,
                    _font.Size, new Point(x, y), sf);
    
                // Rotate string and draw it
                Matrix m = new Matrix();
                m.RotateAt(_angle, new PointF(x, y));
                g.Transform = m;
                g.DrawPath(new Pen(_color), gp);
                g.FillPath(new SolidBrush(_fillcolor), gp);
            }
    
        }

           代码比较简单,注释也比较详细。就不逐一分析了。
           虽然水印效果在第一个工具上已经实现,不过在发放一张福利照片,给深夜忙碌的码农们提提神。(真正的效果在右下角的水印,请注意力集中。谢谢)

          

        

      后语

       如果大家觉得这两个小东西对自己有点用处或者觉得上图妹纸能提升的话,麻烦点击推荐!您的支持就是俺无限的动力。

        最后附上文中示例代码下载(https://files.cnblogs.com/axing/TEST.rar),代码仅供参考.

        最后谢谢大家。


    作者:Stephen-kzx
    出处:http://www.cnblogs.com/axing/
    公众号:会定时分享写工作中或者生活中遇到的小游戏和小工具源码。有兴趣的帮忙点下关注!感恩!
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Linux上安装Tomcat
    SQLServer2008 关于while循环
    [转]接口和抽象类
    windows 装XP系统
    SQLServer2008 表与表之间的数据导入
    问题消灭机
    报错。。。。。。。。。。
    疑问...........
    SQLServer In和Exists
    struts2 访问一个action的时候出现多次重复访问问题(2次或者3次)
  • 原文地址:https://www.cnblogs.com/axing/p/3116328.html
Copyright © 2011-2022 走看看