中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

[原(yuan)創]《C#高級GDI+實戰(zhan):從零開發(fa)一個流程圖》第08章:增加菱形(xing)(xing)、平(ping)行四邊形(xing)(xing)、圓角(jiao)矩(ju)形(xing)(xing),文本居中顯示

一、前言

前面的(de)(de)課(ke)程我們(men)已經完成了形(xing)狀和連線的(de)(de)抽象,并(bing)獨(du)立出了畫布控件(jian),基礎(chu)已經打(da)好,下面就要添磚加瓦了。我們(men)本(ben)(ben)節課(ke)程就來(lai)添加一些(xie)不同的(de)(de)形(xing)狀,如:菱(ling)形(xing)、平行四(si)邊形(xing)、圓(yuan)角(jiao)矩(ju)形(xing)等。而且(qie)我們(men)前面發現形(xing)狀內(nei)的(de)(de)文本(ben)(ben)都(dou)不是居中顯示的(de)(de),我們(men)也順便優化下。

相信看完的你,一定會有所收獲!

本文地址://www.xtjzw.net/lesliexin/p/18997090

二、先看效果

我們可以看到(dao)添加了不同的形狀(zhuang),且都支持拖動、連(lian)線。

看完本篇的代碼,我們會(hui)發現(xian)實現(xian)起來很簡單,只(zhi)需要(yao)給繼承形狀基類實現(xian)下(xia)就行了,主程序只(zhi)是添(tian)加個控件、生成個形狀類,調(diao)用畫布的添(tian)加形狀方法就行了。

所以(yi)本節的課程重點在于如(ru)何去(qu)用GDI+“畫(hua)”出(chu)這(zhe)些形狀。

三、菱形

像菱形及本文中(zhong)的形狀,就沒(mei)有(you)現(xian)在(zai)的GDI+方法來實現(xian)了(le),只(zhi)能(neng)通過各個子方法來組合繪制(zhi)出想要的形狀。

我(wo)們先看下圖的菱形圖示(shi):

image

我(wo)們的(de)所做(zuo)的(de)就是依次(ci)繪制菱形的(de)四(si)(si)個邊,這(zhe)四(si)(si)個頂點的(de)坐標怎么(me)來的(de)呢?

我們在前面的抽象出形狀基類那節講過,屬性Rect是指示形狀所在的矩形區域,所以我們就要在這個矩形區域內,指定4個頂點并計算出坐標。

當有了坐標后,我可以使用(yong)GDI+的(de)AddPolygon方法來將多個坐標點添加成一個多邊形(xing),其MSDN的(de)解(jie)釋(shi)如下:

image

最后(hou)使用GDI+的FillPath將此多邊形繪(hui)制出來(lai),具體的代碼如下:

image

四、平行四邊形

同菱形,我(wo)們(men)也是使用類似的(de)方(fang)法求出四個頂點的(de)坐標(biao),這里我(wo)們(men)將傾斜(xie)距離設置(zhi)為1/5的(de)寬度:

image

代(dai)碼定義里直接按(an)圖(tu)示取值即可(ke):

image

五、圓角矩形

圓角矩形(xing)就和上面的兩個形(xing)狀不一樣(yang)了,因為不再是由直線組成,而是要有弧度:

image

這里(li)要使用(yong)一(yi)個新的(de)GDI+方(fang)法:AddArc,添(tian)加(jia)一(yi)段弧(hu)線,其(qi)MSDN的(de)解(jie)釋如下:

image

注意(yi)看最下面那段話:

如果圖(tu)中有上(shang)一(yi)條直線或曲線,則會添加一(yi)條線,用于將(jiang)上(shang)一(yi)段的(de)端點(dian)連接到弧(hu)線的(de)開(kai)頭。

所以我們并不(bu)需要添(tian)(tian)加4條(tiao)直(zhi)線(xian)4個弧(hu)(hu)線(xian),只(zhi)需要添(tian)(tian)加4個弧(hu)(hu)線(xian)就(jiu)行了(le),我們暫時將弧(hu)(hu)線(xian)所在圓的直(zhi)徑固(gu)定為20。

其中:

1,左上角

image

2,右上角

image

3,右下角

image

4,左下角

image

我們(men)參(can)照上(shang)圖(tu)的坐標及角(jiao)度(du)編寫代(dai)碼即可:

image

六、文本居中顯示

上面的形狀實現后,我(wo)們會發現文本(ben)(ben)位置都不統(tong)一(yi),我(wo)們下面就來讓文本(ben)(ben)統(tong)一(yi)居(ju)中顯(xian)示。

核心是(shi)使用(yong)GDI+的(de)DrawString的(de)一(yi)個(ge)重載方法(fa):

image

我們(men)像下面(mian)這樣寫就能讓文本居中顯示:

image

關于StringFormat的詳細(xi)講解,請參照教程(cheng):

C# StringFormat詳解之文本方向、對齊

//www.xtjzw.net/lesliexin/p/12879270.html

具體(ti)的代碼(ma)改造如(ru)下(xia),不再贅(zhui)述:

點擊查看代碼

    /// <summary>
    /// 菱形定義
    /// </summary>
    public class LozengeShapeV2 : ShapeBase
    {
        public override void Draw(Graphics g)
        {
            var x2 = Rect.X;
            var y2 = Rect.Y;
            var w2 = Rect.Width;
            var h2 = Rect.Height;

            var x = x2 + w2 / 2;
            var y = y2 + h2 / 2;

            //左-上-右-下
            var r0 = new Point(x2, y);
            var r1 = new Point(x, y2);
            var r2 = new Point(x2 + w2, y);
            var r3 = new Point(x, y2 + h2);

            var path = new GraphicsPath();
            path.Reset();
            path.AddPolygon(new Point[]{ r0,r1,r2,r3});
            path.CloseFigure();
            g.FillPath(new SolidBrush(BackgroundColor), path);

            g.DrawString(Text, TextFont, new SolidBrush(FontColor), Rect,
                new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
        }

    }
	
	
    /// <summary>
    /// 平行四邊形定義
    /// </summary>
    public class ParallelogramShapeV2 : ShapeBase
    {
        public override void Draw(Graphics g)
        {
            var x2 = Rect.X;
            var y2 = Rect.Y;
            var w2 = Rect.Width;
            var h2 = Rect.Height;

            var f = w2 / 5;

            //左-上-右-下
            var r0 = new Point(x2 + f, y2);
            var r1 = new Point(x2 + w2, y2);
            var r2 = new Point(x2 + w2 - f, y2 + h2);
            var r3 = new Point(x2, y2 + h2);

            var path = new GraphicsPath();
            path.Reset();
            path.AddPolygon(new Point[]{ r0,r1,r2,r3});
            path.CloseFigure();
            g.FillPath(new SolidBrush(BackgroundColor), path);

            g.DrawString(Text, TextFont, new SolidBrush(FontColor), Rect,
                new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
        }

    }
	
	
    /// <summary>
    /// 圓角矩形定義
    /// </summary>
    public class RoundRectShapeV2 : ShapeBase
    {
        public override void Draw(Graphics g)
        {
            float diameter = 20;

            var path = new GraphicsPath();
            path.Reset();

            RectangleF arc = new RectangleF(Rect.X, Rect.Y, diameter, diameter);
           
            // 左上角
            path.AddArc(arc, 180, 90);

            // 右上角
            arc.X = Rect.Right - diameter;
            path.AddArc(arc, 270, 90);

            // 右下角
            arc.Y = Rect.Bottom - diameter;
            path.AddArc(arc, 0, 90);

            // 左下角
            arc.X = Rect.Left;
            path.AddArc(arc, 90, 90);


            path.CloseFigure();
            g.FillPath(new SolidBrush(BackgroundColor), path);

            g.DrawString(Text, TextFont, new SolidBrush(FontColor), Rect,
                new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
        }

    }

七、添加形狀方法抽象出泛型方法

我(wo)們看(kan)之前添加矩(ju)形和圓(yuan)形的方法:

image

會發(fa)現很類似,類似是因為矩形(xing)和(he)圓形(xing)都是形(xing)狀基類的(de)實(shi)現,那(nei)么我們(men)本節課(ke)程添加(jia)了(le)這三個新的(de)形(xing)狀,再這樣寫就太繁瑣(suo)了(le),我們(men)直接抽象出一個泛型方法來解(jie)決此(ci)問(wen)題(ti):

image

可以(yi)看到,就(jiu)是將生成矩形(xing)和圓形(xing)的方(fang)法使用泛型替代(dai)。

我們(men)再(zai)寫一(yi)個泛型方法來將形狀(zhuang)添加到(dao)畫布(bu):

image

好了(le)(le),到此(ci)我們(men)的代碼就(jiu)進一步簡(jian)化了(le)(le),添(tian)加不(bu)同形狀(zhuang)只(zhi)需要傳入對應(ying)的形狀(zhuang)類型就(jiu)行了(le)(le):

image

是不是很優雅~

完整代碼如下,大家可自行嘗試:

點擊查看代碼
using Elements;
using Elements.Links;
using Elements.Shapes;
using FlowChartCanvas;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FlowChartDemo
{
    public partial class FormDemo07V4 : FormBase
    {
        public FormDemo07V4()
        {
            InitializeComponent();
            DemoTitle = "第09節隨課Demo  Part4";
            DemoNote = "效果:所有形狀內文本居中顯示。";

            //添加畫布控件
            _fcc = new FCCanvasV1();
            _fcc.FCC_LinkColor += _fcc_FCC_LinkColor;
            _fcc.FCC_LinkState += _fcc_FCC_LinkState;
            _fcc.Dock = DockStyle.Fill;
            panel1.Controls.Add(_fcc);

        }

        private void _fcc_FCC_LinkState(string obj)
        {
            toolStripStatusLabel1.Text = obj;
        }

        private Color _fcc_FCC_LinkColor()
        {
            return GetColor(_linkColorIndex++);
        }

        FCCanvasV1 _fcc;

        /// <summary>
        /// 形狀顏色序號
        /// </summary>
        int _shapeColorIndex = 0;
        /// <summary>
        /// 連線顏色序號
        /// </summary>
        int _linkColorIndex = 0;
               
        /// <summary>
        /// 獲取不同的背景顏色
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        Color GetColor(int i)
        {
            switch (i)
            {
                case 0: return Color.Red;
                case 1: return Color.Green;
                case 2: return Color.Blue;
                case 3: return Color.Orange;
                case 4: return Color.Purple;
                default: return Color.Red;
            }
        }

        //注:文章中說明:再次抽象

        /// <summary>
        /// 創建形狀
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="shapeText"></param>
        /// <returns></returns>
        T CreateShape<T>(string shapeText) where T:ShapeBase
        {
            var t = Activator.CreateInstance<T>();
            t.Id = shapeText + Guid.NewGuid().ToString();
            t.Rect = new Rectangle()
            {
                X = 50,
                Y = 50,
                Width = 100,
                Height = 100,
            };
            t.FontColor = Color.White;
            t.BackgroundColor = GetColor(_shapeColorIndex++);
            t.Text = shapeText + _shapeColorIndex;
            t.TextFont = Font;
            return t;
        }

        /// <summary>
        /// 創建指定類型的形狀并添加到當前流程圖畫布中。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="shapeText"></param>
        void CreateShapeAndAddToFCCanvas<T>(string shapeText) where T : ShapeBase
        {
            var sp = CreateShape<T>(shapeText);

            _fcc.FCC_AddShapes(new List<ShapeBase>() { sp });
            _fcc.FCC_Refresh();
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            CreateShapeAndAddToFCCanvas<RectShapeV2>("矩形");
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            CreateShapeAndAddToFCCanvas<EllipseShapeV2>("圓形");
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            CreateShapeAndAddToFCCanvas<LozengeShapeV2>("菱形");
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            CreateShapeAndAddToFCCanvas<ParallelogramShapeV2>("平行四邊形");
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            CreateShapeAndAddToFCCanvas<RoundRectShapeV2>("圓角矩形");
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            _fcc.FCC_StartLink();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            _fcc.FCC_StopLink();
        }

    }


}

八、結語

我們本節課添加(jia)了(le)多個不同的(de)(de)(de)(de)形(xing)狀(zhuang),這些形(xing)狀(zhuang)也是流程圖(tu)中常用的(de)(de)(de)(de)形(xing)狀(zhuang),有了(le)這些基礎,用戶可按自己的(de)(de)(de)(de)需求添加(jia)自己的(de)(de)(de)(de)形(xing)狀(zhuang)。當然現在的(de)(de)(de)(de)形(xing)狀(zhuang)屬性還(huan)很少,會(hui)隨著(zhu)課程的(de)(de)(de)(de)深入而(er)豐(feng)富(fu),以支持(chi)更多效果。

我們(men)還(huan)抽象(xiang)出一(yi)泛型(xing)方法來(lai)簡化添(tian)加形狀的操作,使用起來(lai)很是優雅。

現在基本的(de)形狀都有(you)了,我們下節課就來添加新的(de)連線(xian):貝塞爾曲(qu)線(xian),這個幾乎是最常(chang)見的(de)曲(qu)線(xian)。

同(tong)(tong)時,有了新的連(lian)線,我們(men)還(huan)會增(zeng)加(jia)不同(tong)(tong)的連(lian)接(jie)點用來連(lian)線,而不再(zai)只連(lian)接(jie)形狀(zhuang)的中(zhong)心點。

敬請期待。

感謝(xie)大家的觀看,本(ben)人水平有限(xian),文章不足之處歡(huan)迎(ying)大家評論指正(zheng)。

-[END]-

posted @ 2025-07-30 13:28  leslie_xin  閱讀(2447)  評論(9)    收藏  舉報