【Talk is cheap. Show me the code.】 公众号如有回复不及时的,麻烦点击联系关于我-联系博主,微信我。谢谢!
老帅哥

Stephen-kzx的博客

【Talk is cheap. Show me the code.】【公众号如有回复不及时的,麻烦点击联系关于我-联系博主,微信我。谢谢!】

分享:动态添加控件和公用章水印工具 提供源码下载

  动态添加控件

   需求:最近项目有个小功能,根据配置文件配置的个数,动态在窗体上生成指定个数的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),代码仅供参考.

    最后谢谢大家。

 

 

 

posted @ 2013-06-04 00:33  何以解忧唯有撸码  阅读(4012)  评论(20编辑  收藏  举报