<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [原創]《C#高級GDI+實戰:從零開發一個流程圖》第04章:來個圓形,連線它!

      一、前言

      上一節我們實現了在矩形與矩形之間添加連線,光是矩形太單調了,某些問題也暴露不出來,我們本節就來看一下,如何添加一個圓形,且支持圓形與圓形、圓形與矩形、矩形與矩形間的連線。在這個過程中我們會發現一些問題,這些問題我們后續課程會進行處理,大家也請帶著自己的思考和理解去看。

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

      本文地址:http://www.rzrgm.cn/lesliexin/p/18923109

      二、先看效果

      我們先來看一下本節課整體要實現的效果,先有個整體印象。

      特別說明一下,課程的編寫是根據實際情況實時調整的,所以有時候與視頻無法一一對應,像本篇教程,只需要看視頻中的前半截就行,后半截視頻的講解在下節教課程中。

      本節課程我們要依次實現兩個效果:

      繪制不同顏色顏色的、可拖動的圓形
      連線支持圓形與圓形、圓形與矩形、矩形與矩形間連線

      我們下面就來開始講解。

      三、實現效果1:添加不同顏色的、可拖動的圓形

      有前面幾節課程的基礎,我們不需要過多的講解,和矩形一樣,只是在繪制時繪制成圓的,且拖動時要判斷選的是圓形還是矩形。

      我們下面就來看一下代碼實操。

      1,設計器界面

      image

      很簡單的界面,就兩個按鈕:添加矩形、添加圓形

      2,圓形定義

      就像矩形的定義一樣,我們也定義一個圓形的類,用來描述這個圓形:

      image

      我們注意到圓形核心也是一個Rectangle類型,這是因為GDI+在繪制圓形是需要的就是Rectangle,不過過多糾結:

      image

      因為整個界面我們要添加多個圓形,所以我們定義一個圓形集合:

      image

      在繪制時,依次繪制所有圓形:

      image

      3,鼠標點擊事件

      在鼠標點擊時,我們這里就要多判斷一步:點擊的是圓形?還是矩形?

      image

      4,鼠標移動事件

      在鼠標移動時,我們同樣要判斷當前點按著的是圓形還是矩形,并修改對應形狀的位置。

      image

      5,添加圓形的方法

      和添加矩形一樣,往圓形集合中添加一個圓形:

      image

      好了,代碼很簡單,到此就實現了效果1,下面是完整的代碼,大家試試吧。

      點擊查看代碼
      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 FormDemo03V1 : FormBase
          {
              public FormDemo03V1()
              {
                  InitializeComponent();
                  DemoTitle = "第05節隨課Demo  Part1";
                  DemoNote = "效果:支持添加圓形,支持不同顏色,支持拖動";
              }
      
              /// <summary>
              /// 矩形定義
              /// </summary>
              public class RectShape
              {
                  /// <summary>
                  /// 矩形ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 矩形位置和尺寸
                  /// </summary>
                  public Rectangle Rect { get; set; }
              }
      
              /// <summary>
              /// 圓形定義
              /// </summary>
              public class EllipseShape
              {
                  /// <summary>
                  /// 矩形ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 矩形位置和尺寸
                  /// </summary>
                  public Rectangle Rect { get; set; }
              }
      
      
              /// <summary>
              /// 直線連線定義
              /// </summary>
              public class LineLink
              {
                  /// <summary>
                  /// 連線ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 開始形狀是否是矩形
                  /// </summary>
                  public bool StartShapeIsRect { get; set; }
                  /// <summary>
                  /// 結束開關是否是矩形
                  /// </summary>
                  public bool EndShapeIsRect { get; set; }
                  /// <summary>
                  /// 連線開始形狀ID
                  /// </summary>
                  public string StartShapeId { get; set; }
                  /// <summary>
                  /// 連線結束形狀ID
                  /// </summary>
                  public string EndShapeId { get; set; }
              }
      
              /// <summary>
              /// 矩形集合
              /// </summary>
              List<RectShape> RectShapes = new List<RectShape>();
              /// <summary>
              /// 圓形集合
              /// </summary>
              List<EllipseShape> EllipseShapes = new List<EllipseShape>();
              /// <summary>
              /// 當前界面連線集合
              /// </summary>
              List<LineLink> Links = new List<LineLink>();
      
              /// <summary>
              /// 畫一個矩形(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="shape"></param>
              void DrawRectShape2(Graphics g, RectShape shape)
              {
                  var index = RectShapes.FindIndex(a => a.Id == shape.Id);
                  g.FillRectangle(GetBrush(index), shape.Rect);
                  g.DrawString(shape.Id, Font, Brushes.White, shape.Rect);
              }
      
              /// <summary>
              /// 畫一個圓形(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="shape"></param>
              void DrawEllipseShape2(Graphics g, EllipseShape shape)
              {
                  var index = EllipseShapes.FindIndex(a => a.Id == shape.Id);
                  g.FillEllipse(GetBrush(index), shape.Rect);
                  g.DrawString(shape.Id, Font, Brushes.White, shape.Rect.X+20,shape.Rect.Y+20);            //注:這里可以講一下,要+20,是顯示文本
              }
      
              /// <summary>
              /// 繪制一條連線(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="line"></param>
              void DrawLine2(Graphics g, LineLink line)
              {
                  //通過連線的開始形狀ID和結束形狀ID,計算兩個形狀的中心點坐標
                  var startPoint = line.StartShapeIsRect? GetCentertPointRect(line.StartShapeId):
                      GetCentertPointEllipse(line.StartShapeId);
                  var endPoint =line.EndShapeIsRect? GetCentertPointRect(line.EndShapeId) : 
                      GetCentertPointEllipse(line.EndShapeId);
      
                  var index = Links.FindIndex(a => a.Id == line.Id);
                  //繪制一條直線
                  g.DrawLine(GetPen(index), startPoint, endPoint);
              }
      
              /// <summary>
              /// 重新繪制當前所有矩形和連線
              /// </summary>
              /// <param name="g"></param>
              void DrawAll(Graphics g)
              {
                  g.Clear(panel1.BackColor);
                  //繪制所有矩形
                  foreach (var sp in RectShapes)
                  {
                      DrawRectShape2(g, sp);
                  }
                  //繪制所有圓形
                  foreach (var sp in EllipseShapes)
                  {
                      DrawEllipseShape2(g, sp);
                  }
                  //繪制所有連線
                  foreach (var ln in Links)
                  {
                      DrawLine2(g, ln);
                  }
              }
      
              //注:文章中說明;此處不過于抽象,后續章節會有
      
              /// <summary>
              /// 當前是否有鼠標按下,且有矩形被選中
              /// </summary>
              bool _isMouseDown = false;
              /// <summary>
              /// 是否是矩形被選中,不是則是圓形
              /// </summary>
              bool _isRectMouseDown = true;
              /// <summary>
              /// 最后一次鼠標的位置
              /// </summary>
              Point _lastMouseLocation = Point.Empty;
              /// <summary>
              /// 當前被鼠標選中的矩形
              /// </summary>
              RectShape _selectedRectShape = null;
              /// <summary>
              /// 當前被鼠標選中的圓形
              /// </summary>
              EllipseShape _selectedEllipseShape = null;
      
              /// <summary>
              /// 獲取不同的背景顏色
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              Brush GetBrush(int i)
              {
                  switch (i)
                  {
                      case 0: return Brushes.Red;
                      case 1: return Brushes.Green;
                      case 2: return Brushes.Blue;
                      case 3: return Brushes.Orange;
                      case 4: return Brushes.Purple;
                      default: return Brushes.Red;
                  }
              }
              /// <summary>
              /// 獲取不同的畫筆顏色
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              Pen GetPen(int i)
              {
                  return new Pen(GetBrush(i), 2);
              }
      
              /// <summary>
              /// 根據形狀ID獲取形狀的中心點,以作為連線的起點或終點
              /// </summary>
              /// <param name="shapeId"></param>
              /// <returns></returns>
              Point GetCentertPointRect(string shapeId)
              {
                  var sp = RectShapes.Find(a => a.Id == shapeId);
                  if (sp != null)
                  {
                      var line1X = sp.Rect.X + sp.Rect.Width / 2;
                      var line1Y = sp.Rect.Y + sp.Rect.Height / 2;
                      return new Point(line1X, line1Y);
                  }
                  return Point.Empty;
              }
              /// <summary>
              /// 根據形狀ID獲取形狀的中心點,以作為連線的起點或終點
              /// </summary>
              /// <param name="shapeId"></param>
              /// <returns></returns>
              Point GetCentertPointEllipse(string shapeId)
              {
                  var sp = EllipseShapes.Find(a => a.Id == shapeId);
                  if (sp != null)
                  {
                      var line1X = sp.Rect.X + sp.Rect.Width / 2;
                      var line1Y = sp.Rect.Y + sp.Rect.Height / 2;
                      return new Point(line1X, line1Y);
                  }
                  return Point.Empty;
              }
      
      
              private void toolStripButton1_Click(object sender, EventArgs e)
              {
                  var rs = new RectShape()
                  {
                      Id = "矩形" + (RectShapes.Count + 1),
                      Rect = new Rectangle()
                      {
                          X = 50,
                          Y = 50,
                          Width = 100,
                          Height = 100,
                      },
                  };
                  RectShapes.Add(rs);
      
                  //重繪所有矩形
                  DrawAll(panel1.CreateGraphics());
              }
      
              private void panel1_MouseDown(object sender, MouseEventArgs e)
              {
                  //當鼠標按下時
      
                  //取最上方的矩形,也就是最后添加的矩形
                  var sp = RectShapes.FindLast(a => a.Rect.Contains(e.Location));
                  //取最上方的圓形,也就是最后添加的圓形
                  var ep = EllipseShapes.FindLast(a => a.Rect.Contains(e.Location));
      
                  //注:說明,這里是簡化情況,因為是兩個LIST,無法判斷序號,就先判斷矩形
      
                  //當前沒有處理連線狀態
                  if (sp != null)
                  {
                      //設置狀態及選中矩形
                      _isMouseDown = true;
                      _lastMouseLocation = e.Location;
                      _selectedRectShape = sp;
                      _selectedEllipseShape = null;
                      _isRectMouseDown = true;
                  }
                  else if (ep != null)
                  {
                      //設置狀態及選中圓形
                      _isMouseDown = true;
                      _lastMouseLocation = e.Location;
                      _selectedRectShape = null;
                      _selectedEllipseShape = ep;
                      _isRectMouseDown = false;
                  }
              }
      
              private void panel1_MouseMove(object sender, MouseEventArgs e)
              {
                  if (_isMouseDown)
                  {
                      //當且僅當:有鼠標按下且有矩形被選中時,才進行后續操作
                      //改變選中矩形的位置信息,隨著鼠標移動而移動
      
                      //計算鼠標位置變化信息
                      var moveX = e.Location.X - _lastMouseLocation.X;
                      var moveY = e.Location.Y - _lastMouseLocation.Y;
      
                      //將選中形狀的位置進行同樣的變化
                      if (_isRectMouseDown)
                      {
                          var oldXY = _selectedRectShape.Rect.Location;
                          oldXY.Offset(moveX, moveY);
                          _selectedRectShape.Rect = new Rectangle(oldXY, _selectedRectShape.Rect.Size);
      
                      }
                      else
                      {
                          var oldXY = _selectedEllipseShape.Rect.Location;
                          oldXY.Offset(moveX, moveY);
                          _selectedEllipseShape.Rect = new Rectangle(oldXY, _selectedEllipseShape.Rect.Size);
      
                      }
      
                      //記錄當前鼠標位置
                      _lastMouseLocation.Offset(moveX, moveY);
      
                      //重繪所有矩形
                      DrawAll(panel1.CreateGraphics());
                  }
              }
      
              private void panel1_MouseUp(object sender, MouseEventArgs e)
              {
                  //當鼠標松開時
                  if (_isMouseDown)
                  {
                      //當且僅當:有鼠標按下且有矩形被選中時,才進行后續操作
      
                      //重置相關記錄信息
                      _isMouseDown = false;
                      _lastMouseLocation = Point.Empty;
                      _selectedRectShape = null;
                      _selectedEllipseShape = null;
                  }
              }
      
              private void toolStripButton4_Click(object sender, EventArgs e)
              {
                  var rs = new EllipseShape()
                  {
                      Id = "圓形" + (EllipseShapes.Count + 1),
                      Rect = new Rectangle()
                      {
                          X = 50,
                          Y = 50,
                          Width = 100,
                          Height = 100,
                      },
                  };
                  EllipseShapes.Add(rs);
      
                  //重繪所有矩形
                  DrawAll(panel1.CreateGraphics());
              }
          }
      
      
      }
      
      

      四、實現效果2:連線支持圓形與圓形、圓形與矩形、矩形與矩形間連線

      上一小節我們添加上了圓形,下面就來支持連線。

      1,設計器界面

      我們在上節的基礎上稍做添加:

      image

      2,連線定義修改

      因為我們要支持圓形與矩形間不同組合的連線,所以我們需要對連線定義進行擴展:

      image

      我們增加了兩個布爾變量,來標識開始形狀和結束形狀是否是矩形,不是矩形則是圓形。

      注:各位讀者看到這里,可能會感覺很死板和繁瑣。是的,確實如此。我們現在是剛開始起步,所以要從簡入深,從繁化簡,也是在這樣一步步深入,我們明白了其中的痛點,引導著我們去調整、去優化。大概下下節課,我們就會使用抽象大法,到時一切都會變得優雅。

      3,繪制連線

      在繪制連線時,我們通過判斷形狀是圓形還是矩形,來取不同的中心點,并繪制連線。

      注:當然,現在連線的是形狀的圓心,所以并沒有太大的區別。

      image

      image

      4,鼠標點擊事件

      這部分不難理解但會比較繁瑣,在判斷是否連線時,還要判斷開始形狀與結束形狀的類型等。

      image

      剩下的就和上一小節沒多少差別了,不再贅述。下面是完整的代碼,大家可以參照嘗試。

      點擊查看代碼
      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 FormDemo03V2 : FormBase
          {
              public FormDemo03V2()
              {
                  InitializeComponent();
                  DemoTitle = "第05節隨課Demo  Part2";
                  DemoNote = "效果:支持矩形與矩形間連線、矩形與圓形間連線、圓形與圓形間連線";
              }
      
              /// <summary>
              /// 矩形定義
              /// </summary>
              public class RectShape
              {
                  /// <summary>
                  /// 矩形ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 矩形位置和尺寸
                  /// </summary>
                  public Rectangle Rect { get; set; }
              }
      
              /// <summary>
              /// 圓形定義
              /// </summary>
              public class EllipseShape
              {
                  /// <summary>
                  /// 矩形ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 矩形位置和尺寸
                  /// </summary>
                  public Rectangle Rect { get; set; }
              }
      
      
              /// <summary>
              /// 直線連線定義
              /// </summary>
              public class LineLink
              {
                  /// <summary>
                  /// 連線ID
                  /// </summary>
                  public string Id { get; set; }
                  /// <summary>
                  /// 開始形狀是否是矩形
                  /// </summary>
                  public bool StartShapeIsRect { get; set; }
                  /// <summary>
                  /// 結束開關是否是矩形
                  /// </summary>
                  public bool EndShapeIsRect { get; set; }
                  /// <summary>
                  /// 連線開始形狀ID
                  /// </summary>
                  public string StartShapeId { get; set; }
                  /// <summary>
                  /// 連線結束形狀ID
                  /// </summary>
                  public string EndShapeId { get; set; }
              }
      
              /// <summary>
              /// 矩形集合
              /// </summary>
              List<RectShape> RectShapes = new List<RectShape>();
              /// <summary>
              /// 圓形集合
              /// </summary>
              List<EllipseShape> EllipseShapes = new List<EllipseShape>();
              /// <summary>
              /// 當前界面連線集合
              /// </summary>
              List<LineLink> Links = new List<LineLink>();
      
              /// <summary>
              /// 畫一個矩形(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="shape"></param>
              void DrawRectShape2(Graphics g, RectShape shape)
              {
                  var index = RectShapes.FindIndex(a => a.Id == shape.Id);
                  g.FillRectangle(GetBrush(index), shape.Rect);
                  g.DrawString(shape.Id, Font, Brushes.White, shape.Rect);
              }
      
              /// <summary>
              /// 畫一個圓形(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="shape"></param>
              void DrawEllipseShape2(Graphics g, EllipseShape shape)
              {
                  var index = EllipseShapes.FindIndex(a => a.Id == shape.Id);
                  g.FillEllipse(GetBrush(index), shape.Rect);
                  g.DrawString(shape.Id, Font, Brushes.White, shape.Rect.X+20,shape.Rect.Y+20);            //注:這里可以講一下,要+20,是顯示文本
              }
      
              /// <summary>
              /// 繪制一條連線(不同顏色)
              /// </summary>
              /// <param name="g"></param>
              /// <param name="line"></param>
              void DrawLine2(Graphics g, LineLink line)
              {
                  //通過連線的開始形狀ID和結束形狀ID,計算兩個形狀的中心點坐標
                  var startPoint = line.StartShapeIsRect? GetCentertPointRect(line.StartShapeId): GetCentertPointEllipse(line.StartShapeId);
                  var endPoint =line.EndShapeIsRect? GetCentertPointRect(line.EndShapeId) : GetCentertPointEllipse(line.EndShapeId);
      
                  var index = Links.FindIndex(a => a.Id == line.Id);
                  //繪制一條直線
                  g.DrawLine(GetPen(index), startPoint, endPoint);
              }
      
              /// <summary>
              /// 重新繪制當前所有矩形和連線
              /// </summary>
              /// <param name="g"></param>
              void DrawAll(Graphics g)
              {
                  g.Clear(panel1.BackColor);
                  //繪制所有矩形
                  foreach (var sp in RectShapes)
                  {
                      DrawRectShape2(g, sp);
                  }
                  //繪制所有圓形
                  foreach (var sp in EllipseShapes)
                  {
                      DrawEllipseShape2(g, sp);
                  }
                  //繪制所有連線
                  foreach (var ln in Links)
                  {
                      DrawLine2(g, ln);
                  }
              }
      
              //注:文章中說明;此處不過于抽象,后續章節會有
      
              /// <summary>
              /// 當前是否有鼠標按下,且有矩形被選中
              /// </summary>
              bool _isMouseDown = false;
              /// <summary>
              /// 是否是矩形被選中,不是則是圓形
              /// </summary>
              bool _isRectMouseDown = true;
              /// <summary>
              /// 最后一次鼠標的位置
              /// </summary>
              Point _lastMouseLocation = Point.Empty;
              /// <summary>
              /// 當前被鼠標選中的矩形
              /// </summary>
              RectShape _selectedRectShape = null;
              /// <summary>
              /// 當前被鼠標選中的圓形
              /// </summary>
              EllipseShape _selectedEllipseShape = null;
              /// <summary>
              /// 添加連線時選中的第一個是否是矩形,不是則是圓形
              /// </summary>
              bool _selectedStartIsRect = true;
              /// <summary>
              /// 添加連線時選中的第一個矩形
              /// </summary>
              RectShape _selectedStartRectShape = null;
              /// <summary>
              /// 添加連線時選中的第一個圓形
              /// </summary>
              EllipseShape _selectedStartEllipseShape = null;
              /// <summary>
              /// 添加連線時選中的第二個是否是矩形,不是則是圓形
              /// </summary>
              bool _selectedEndIsRect = true;
              /// <summary>
              /// 添加連線時選中的第二個矩形
              /// </summary>
              RectShape _selectedEndRectShape = null;
              /// <summary>
              /// 添加連線時選中的第二個圓形
              /// </summary>
              EllipseShape _selectedEndEllipseShape = null;
              /// <summary>
              /// 是否正添加連線
              /// </summary>
              bool _isAddLink = false;
      
              /// <summary>
              /// 獲取不同的背景顏色
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              Brush GetBrush(int i)
              {
                  switch (i)
                  {
                      case 0: return Brushes.Red;
                      case 1: return Brushes.Green;
                      case 2: return Brushes.Blue;
                      case 3: return Brushes.Orange;
                      case 4: return Brushes.Purple;
                      default: return Brushes.Red;
                  }
              }
              /// <summary>
              /// 獲取不同的畫筆顏色
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              Pen GetPen(int i)
              {
                  return new Pen(GetBrush(i), 2);
              }
      
              /// <summary>
              /// 根據形狀ID獲取形狀的中心點,以作為連線的起點或終點
              /// </summary>
              /// <param name="shapeId"></param>
              /// <returns></returns>
              Point GetCentertPointRect(string shapeId)
              {
                  var sp = RectShapes.Find(a => a.Id == shapeId);
                  if (sp != null)
                  {
                      var line1X = sp.Rect.X + sp.Rect.Width / 2;
                      var line1Y = sp.Rect.Y + sp.Rect.Height / 2;
                      return new Point(line1X, line1Y);
                  }
                  return Point.Empty;
              }
              /// <summary>
              /// 根據形狀ID獲取形狀的中心點,以作為連線的起點或終點
              /// </summary>
              /// <param name="shapeId"></param>
              /// <returns></returns>
              Point GetCentertPointEllipse(string shapeId)
              {
                  var sp = EllipseShapes.Find(a => a.Id == shapeId);
                  if (sp != null)
                  {
                      var line1X = sp.Rect.X + sp.Rect.Width / 2;
                      var line1Y = sp.Rect.Y + sp.Rect.Height / 2;
                      return new Point(line1X, line1Y);
                  }
                  return Point.Empty;
              }
      
      
              private void toolStripButton1_Click(object sender, EventArgs e)
              {
                  var rs = new RectShape()
                  {
                      Id = "矩形" + (RectShapes.Count + 1),
                      Rect = new Rectangle()
                      {
                          X = 50,
                          Y = 50,
                          Width = 100,
                          Height = 100,
                      },
                  };
                  RectShapes.Add(rs);
      
                  //重繪所有矩形
                  DrawAll(panel1.CreateGraphics());
              }
      
              private void panel1_MouseDown(object sender, MouseEventArgs e)
              {
                  //當鼠標按下時
      
                  //取最上方的矩形,也就是最后添加的矩形
                  var sp = RectShapes.FindLast(a => a.Rect.Contains(e.Location));
                  //取最上方的圓形,也就是最后添加的圓形
                  var ep = EllipseShapes.FindLast(a => a.Rect.Contains(e.Location));
      
                  if (!_isAddLink)
                  {
                      //注:說明,這里是簡化情況,因為是兩個LIST,無法判斷序號,就先判斷矩形
                      
                      //當前沒有處理連線狀態
                      if (sp != null)
                      {
                          //設置狀態及選中矩形
                          _isMouseDown = true;
                          _lastMouseLocation = e.Location;
                          _selectedRectShape = sp;
                          _selectedEllipseShape = null;
                          _isRectMouseDown = true;
                      }
                      else if (ep != null)
                      {
                          //設置狀態及選中圓形
                          _isMouseDown = true;
                          _lastMouseLocation = e.Location;
                          _selectedRectShape = null;
                          _selectedEllipseShape = ep;
                          _isRectMouseDown = false;
                      }
                  }
                  else
                  {
                      //正在添加連線
      
                      if (_selectedStartRectShape == null && _selectedStartEllipseShape == null)
                      {
                          //證明沒有矩形和圓形被選中則設置開始形狀
                          if (sp != null)
                          {
                              //設置開始形狀是矩形
                              _selectedStartRectShape = sp;
                              _selectedStartEllipseShape = null;
                              _selectedStartIsRect = true;
                          }
                          else if (ep != null)
                          {
                              //設置開始形狀是圓形
                              _selectedStartRectShape = null;
                              _selectedStartEllipseShape = ep;
                              _selectedStartIsRect = false;
                          }
                          toolStripStatusLabel1.Text = "請點擊第2個形狀";
                      }
                      else
                      {
                          //判斷第2個形狀是否是第1個形狀
                          if (sp != null)
                          {
                              //證明當前選中的是矩形
                              if (_selectedStartRectShape != null)
                              {
                                  //證明第1步選中的矩形
      
                                  //判斷當前選中的矩形是否是第1步選中的矩形
                                  if (_selectedStartRectShape.Id == sp.Id)
                                  {
                                      toolStripStatusLabel1.Text = "不可選擇同一個形狀,請重新點擊第2個形狀";
                                      return;
                                  }
                              }
                          }
                          else if (ep != null)
                          {
                              //證明當前選中的圓形
                              if (_selectedStartEllipseShape != null)
                              {
                                  //證明第1步選中的矩形
      
                                  //判斷當前選中的矩形是否是第1步選中的矩形
                                  if (_selectedStartEllipseShape.Id == ep.Id)
                                  {
                                      toolStripStatusLabel1.Text = "不可選擇同一個形狀,請重新點擊第2個形狀";
                                      return;
                                  }
                              }
                          }
      
                          //注:文章中說明:因為太過復雜,且不是本節重點,但不再進行去重判斷
      
                          if (sp != null)
                          {
                              //設置結束形狀是矩形
                              _selectedEndRectShape = sp;
                              _selectedEndEllipseShape = null;
                              _selectedEndIsRect = true;
                          }
                          else if (ep != null)
                          {
                              //設置結束形狀是圓形
                              _selectedEndRectShape = null;
                              _selectedEndEllipseShape = ep;
                              _selectedEndIsRect = false;
                          }
                          else
                          {
                              return;
                          }
      
                          //兩個形狀都設置了,便添加一條新連線
                          Links.Add(new LineLink()
                          {
                              Id = "連線" + (Links.Count + 1),
                              StartShapeId =_selectedStartIsRect? _selectedStartRectShape.Id:_selectedStartEllipseShape.Id,
                              EndShapeId =_selectedEndIsRect? _selectedEndRectShape.Id:_selectedEndEllipseShape.Id,
                              StartShapeIsRect=_selectedStartIsRect,
                              EndShapeIsRect=_selectedEndIsRect,
                          });
                          //兩個形狀都已選擇,結束添加連線狀態
                          _isAddLink = false;
                          toolStripStatusLabel1.Text = "";
                          //重繪以顯示連線
                          DrawAll(panel1.CreateGraphics());
      
                      }
                  }
      
              }
      
              private void panel1_MouseMove(object sender, MouseEventArgs e)
              {
                  //當鼠標移動時
      
                  //如果處于添加連線時,則不移動形狀
                  if (_isAddLink) return;
      
                  if (_isMouseDown)
                  {
                      //當且僅當:有鼠標按下且有矩形被選中時,才進行后續操作
      
                      //改變選中矩形的位置信息,隨著鼠標移動而移動
      
                      //計算鼠標位置變化信息
                      var moveX = e.Location.X - _lastMouseLocation.X;
                      var moveY = e.Location.Y - _lastMouseLocation.Y;
      
                      //將選中形狀的位置進行同樣的變化
                      if (_isRectMouseDown)
                      {
                          var oldXY = _selectedRectShape.Rect.Location;
                          oldXY.Offset(moveX, moveY);
                          _selectedRectShape.Rect = new Rectangle(oldXY, _selectedRectShape.Rect.Size);
      
                      }
                      else
                      {
                          var oldXY = _selectedEllipseShape.Rect.Location;
                          oldXY.Offset(moveX, moveY);
                          _selectedEllipseShape.Rect = new Rectangle(oldXY, _selectedEllipseShape.Rect.Size);
      
                      }
      
                      //記錄當前鼠標位置
                      _lastMouseLocation.Offset(moveX, moveY);
      
                      //重繪所有矩形
                      DrawAll(panel1.CreateGraphics());
                  }
      
              }
      
              private void panel1_MouseUp(object sender, MouseEventArgs e)
              {
                  //當鼠標松開時
                  if (_isMouseDown)
                  {
                      //當且僅當:有鼠標按下且有矩形被選中時,才進行后續操作
      
                      //重置相關記錄信息
                      _isMouseDown = false;
                      _lastMouseLocation = Point.Empty;
                      _selectedRectShape = null;
                      _selectedEllipseShape = null;
                  }
              }
      
              private void toolStripButton2_Click(object sender, EventArgs e)
              {
                  _isAddLink = true;
                  _selectedStartRectShape = null;
                  _selectedEndRectShape = null;
                  _selectedStartEllipseShape = null;
                  _selectedEndEllipseShape = null;
                  toolStripStatusLabel1.Text = "請點擊第1個形狀";
              }
      
              private void toolStripButton3_Click(object sender, EventArgs e)
              {
                  _isAddLink = false;
                  _selectedStartRectShape = null;
                  _selectedEndRectShape = null;
                  toolStripStatusLabel1.Text = "";
                  DrawAll(panel1.CreateGraphics());
              }
      
              private void toolStripButton4_Click(object sender, EventArgs e)
              {
                  var rs = new EllipseShape()
                  {
                      Id = "圓形" + (EllipseShapes.Count + 1),
                      Rect = new Rectangle()
                      {
                          X = 50,
                          Y = 50,
                          Width = 100,
                          Height = 100,
                      },
                  };
                  EllipseShapes.Add(rs);
      
                  //重繪所有矩形
                  DrawAll(panel1.CreateGraphics());
              }
          }
      
      
      }
      
      

      五、結語

      本一小節總體而言很簡單,就是增加一個新的形狀:圓形。但是在代碼流程上卻復雜很多,這也是我們后面課程使用抽象來優化的原因之一。

      下節課我們就來到了顯示效果優化部分了,除了顯示質量外,還有拖動時閃爍的問題也會同步解決。敬請期待。

      感謝大家的觀看,本人水平有限,文章不足之處歡迎大家評論指正。

      -[END]-

      posted @ 2025-06-25 11:01  leslie_xin  閱讀(674)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 亚洲精品入口一区二区乱| 国产午夜福利片在线观看| 精品一区二区三区在线视频观看| 国产精品极品美女自在线观看免费| 久热色视频精品在线观看| 国产高清国产精品国产专区| 国产免费高清69式视频在线观看| 国产精品亚洲中文字幕| 和艳妇在厨房好爽在线观看| 深田えいみ禁欲后被隔壁人妻| 日本人成精品视频在线| 成人3D动漫一区二区三区| 午夜福利国产精品小视频| 双乳奶水饱满少妇呻吟免费看| 亚洲色大成网站WWW永久麻豆| 大又大又粗又硬又爽少妇毛片| 日本国产一区二区三区在线观看 | 精品国产制服丝袜高跟| 农民人伦一区二区三区| 不卡国产一区二区三区| 国产爆乳无码av在线播放| 无码av天天av天天爽| 亚洲综合无码AV在线观看| 日韩国产中文字幕精品| 国产精品一码二码三码四码 | 欧洲美熟女乱又伦AV影片| 天堂mv在线mv免费mv香蕉| 亚洲国产亚洲综合在线尤物| 麻豆成人av不卡一二三区| 肉大捧一进一出免费视频| 国产精品久久久午夜夜伦鲁鲁| 精品国产中文字幕懂色| 国产乱码精品一区二三区| 国产精品无码专区| 国产精品日日摸夜夜添夜夜添2021| 国产成人精品永久免费视频| 在线a人片免费观看| 成人免费A级毛片无码网站入口| 久热这里只有精品12| 免费人成自慰网站| 久久精品国产男包|