TableBase.DesignExt.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. using FastReport.Controls;
  2. using FastReport.Utils;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Drawing;
  7. using System.Windows.Forms;
  8. namespace FastReport.Table
  9. {
  10. internal enum MouseMode
  11. {
  12. None,
  13. SelectColumn,
  14. SelectRow,
  15. SelectCell,
  16. ResizeColumn,
  17. ResizeRow
  18. }
  19. partial class TableBase
  20. {
  21. #region Private Fields
  22. private static Cursor curDownArrow = ResourceLoader.GetCursor("DownArrow.cur");
  23. private static Cursor curRightArrow = ResourceLoader.GetCursor("RightArrow.cur");
  24. private TableClipboard clipboard;
  25. private MouseMode mouseMode;
  26. private Point startSelectionPoint;
  27. #endregion Private Fields
  28. #region Public Properties
  29. /// <summary>
  30. /// This property is not relevant to this class.
  31. /// </summary>
  32. [Browsable(false)]
  33. public new BreakableComponent BreakTo
  34. {
  35. get { return base.BreakTo; }
  36. set { base.BreakTo = value; }
  37. }
  38. /// <summary>
  39. /// This property is not relevant to this class.
  40. /// </summary>
  41. [Browsable(false)]
  42. public new bool CanGrow
  43. {
  44. get { return base.CanGrow; }
  45. set { base.CanGrow = value; }
  46. }
  47. /// <summary>
  48. /// This property is not relevant to this class.
  49. /// </summary>
  50. [Browsable(false)]
  51. public new bool CanShrink
  52. {
  53. get { return base.CanShrink; }
  54. set { base.CanShrink = value; }
  55. }
  56. /// <inheritdoc/>
  57. public override float Height
  58. {
  59. get { return base.Height; }
  60. set
  61. {
  62. if (IsDesigning && !lockColumnRowChange)
  63. {
  64. foreach (TableRow r in Rows)
  65. {
  66. r.Height += (value - base.Height) / Rows.Count;
  67. }
  68. }
  69. base.Height = value;
  70. }
  71. }
  72. /// <summary>
  73. /// This property is not relevant to this class.
  74. /// </summary>
  75. [Browsable(false)]
  76. public new Hyperlink Hyperlink
  77. {
  78. get { return base.Hyperlink; }
  79. }
  80. /// <inheritdoc/>
  81. public override bool IsSelected
  82. {
  83. get
  84. {
  85. if (Report == null)
  86. return false;
  87. return Report.Designer.SelectedObjects.IndexOf(this) != -1 || IsInternalSelected;
  88. }
  89. }
  90. /// <inheritdoc/>
  91. public override float Width
  92. {
  93. get { return base.Width; }
  94. set
  95. {
  96. if (IsDesigning && !lockColumnRowChange)
  97. {
  98. foreach (TableColumn c in Columns)
  99. {
  100. c.Width += (value - base.Width) / Columns.Count;
  101. }
  102. }
  103. base.Width = value;
  104. }
  105. }
  106. #endregion Public Properties
  107. #region Internal Properties
  108. internal TableClipboard Clipboard
  109. {
  110. get
  111. {
  112. if (clipboard == null)
  113. clipboard = new TableClipboard(this);
  114. return clipboard;
  115. }
  116. }
  117. internal MouseMode MouseMode
  118. {
  119. get { return mouseMode; }
  120. set { mouseMode = value; }
  121. }
  122. #endregion Internal Properties
  123. #region Private Properties
  124. private bool IsInternalSelected
  125. {
  126. get
  127. {
  128. if (Report == null)
  129. return false;
  130. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  131. return selection.Count > 0 && (
  132. (selection[0] is TableRow && (selection[0] as TableRow).Parent == this) ||
  133. (selection[0] is TableColumn && (selection[0] as TableColumn).Parent == this) ||
  134. (selection[0] is TableCell && (selection[0] as TableCell).Parent != null && (selection[0] as TableCell).Parent.Parent == this));
  135. }
  136. }
  137. #endregion Private Properties
  138. #region Public Methods
  139. /// <inheritdoc/>
  140. public override ContextMenuBase GetContextMenu()
  141. {
  142. return new TableObjectMenu(Report.Designer);
  143. }
  144. /// <inheritdoc/>
  145. public override void HandleKeyDown(Control sender, KeyEventArgs e)
  146. {
  147. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  148. if (!IsSelected || !(selection[0] is TableCell))
  149. return;
  150. TableCell topCell = selection[0] as TableCell;
  151. int left = topCell.Address.X;
  152. int top = topCell.Address.Y;
  153. bool selectionChanged = false;
  154. switch (e.KeyCode)
  155. {
  156. case Keys.Enter:
  157. topCell.HandleKeyDown(sender, e);
  158. break;
  159. case Keys.Delete:
  160. foreach (Base c in selection)
  161. {
  162. if (c is TableCell)
  163. (c as TableCell).Text = "";
  164. }
  165. Report.Designer.SetModified(null, "Change", Name);
  166. break;
  167. case Keys.Up:
  168. top--;
  169. selectionChanged = true;
  170. break;
  171. case Keys.Down:
  172. top += topCell.RowSpan;
  173. selectionChanged = true;
  174. break;
  175. case Keys.Left:
  176. left--;
  177. selectionChanged = true;
  178. break;
  179. case Keys.Right:
  180. left += topCell.ColSpan;
  181. selectionChanged = true;
  182. break;
  183. }
  184. if (selectionChanged)
  185. {
  186. if (left < 0)
  187. left = 0;
  188. if (left >= Columns.Count)
  189. left = Columns.Count - 1;
  190. if (top < 0)
  191. top = 0;
  192. if (top >= Rows.Count)
  193. top = Rows.Count - 1;
  194. mouseMode = MouseMode.SelectCell;
  195. SetSelection(left, top, left, top);
  196. Report.Designer.SelectionChanged(null);
  197. }
  198. e.Handled = true;
  199. }
  200. /// <inheritdoc/>
  201. public override void HandleMouseDown(FRMouseEventArgs e)
  202. {
  203. if (mouseMode == MouseMode.None)
  204. {
  205. HandleMouseHover(e);
  206. if (e.handled)
  207. {
  208. e.mode = WorkspaceMode2.Move;
  209. if (IsSelected)
  210. {
  211. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  212. if (!selection.Contains(this))
  213. {
  214. selection.Clear();
  215. selection.Add(this);
  216. }
  217. }
  218. }
  219. else
  220. {
  221. if (PointInObject(new PointF(e.x, e.y)))
  222. {
  223. e.handled = true;
  224. e.mode = WorkspaceMode2.Custom;
  225. e.activeObject = this;
  226. mouseMode = MouseMode.SelectCell;
  227. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  228. if (e.button == MouseButtons.Left)
  229. {
  230. startSelectionPoint = GetAddressAtMousePoint(new PointF(e.x, e.y), true);
  231. TableCell cell = this[startSelectionPoint.X, startSelectionPoint.Y];
  232. if (e.modifierKeys == Keys.Shift)
  233. {
  234. // toggle selection
  235. if (selection.Contains(cell))
  236. {
  237. if (selection.Count > 1)
  238. selection.Remove(cell);
  239. }
  240. else
  241. selection.Add(cell);
  242. }
  243. else
  244. {
  245. selection.Clear();
  246. selection.Add(cell);
  247. }
  248. }
  249. else if (e.button == MouseButtons.Right)
  250. {
  251. Point selectionPoint = GetAddressAtMousePoint(new PointF(e.x, e.y), true);
  252. Rectangle selectionRect = GetSelectionRect();
  253. if (!selectionRect.Contains(selectionPoint))
  254. {
  255. selection.Clear();
  256. selection.Add(this[selectionPoint.X, selectionPoint.Y]);
  257. }
  258. }
  259. }
  260. }
  261. }
  262. else if (e.button == MouseButtons.Left)
  263. {
  264. startSelectionPoint = GetAddressAtMousePoint(new PointF(e.x, e.y), false);
  265. if (mouseMode == MouseMode.SelectColumn)
  266. SetSelection(startSelectionPoint.X, 0, startSelectionPoint.X, Rows.Count - 1);
  267. else if (mouseMode == MouseMode.SelectRow)
  268. SetSelection(0, startSelectionPoint.Y, Columns.Count - 1, startSelectionPoint.Y);
  269. }
  270. }
  271. /// <inheritdoc/>
  272. public override void HandleMouseHover(FRMouseEventArgs e)
  273. {
  274. if (IsSelected)
  275. {
  276. float m = 1 / Report.Designer.Zoom;
  277. if (new RectangleF(AbsLeft + 8 * m, AbsTop - 8 * m, 16 * m, 16 * m).Contains(new PointF(e.x, e.y)))
  278. {
  279. e.handled = true;
  280. e.cursor = Cursors.SizeAll;
  281. }
  282. }
  283. }
  284. /// <inheritdoc/>
  285. public override void HandleMouseMove(FRMouseEventArgs e)
  286. {
  287. base.HandleMouseMove(e);
  288. if (!e.handled && e.button == MouseButtons.None)
  289. {
  290. PointF point = new PointF(e.x, e.y);
  291. mouseMode = MouseMode.None;
  292. // don't process if mouse is over move area
  293. HandleMouseHover(e);
  294. if (e.handled)
  295. {
  296. e.handled = false;
  297. return;
  298. }
  299. // check column resize or select
  300. if (IsSelected)
  301. {
  302. float left = AbsLeft;
  303. for (int x = 0; x < Columns.Count; x++)
  304. {
  305. float width = Columns[x].Width;
  306. left += width;
  307. if (point.Y > AbsTop && point.Y < AbsBottom && point.X > left - 3 && point.X < left + 3)
  308. {
  309. // column resize
  310. PointF pt = new PointF(e.x + 3, e.y);
  311. Point pt1 = GetAddressAtMousePoint(pt, false);
  312. Point pt2 = GetAddressAtMousePoint(pt, true);
  313. // check if we are in span
  314. if (pt1 == pt2)
  315. {
  316. mouseMode = MouseMode.ResizeColumn;
  317. e.cursor = Cursors.VSplit;
  318. e.data = Columns[x];
  319. break;
  320. }
  321. }
  322. else if (point.Y > AbsTop - 8 && point.Y < AbsTop + 2 && point.X > left - width && point.X < left)
  323. {
  324. // column select
  325. mouseMode = MouseMode.SelectColumn;
  326. e.cursor = curDownArrow;
  327. e.data = Columns[x];
  328. break;
  329. }
  330. }
  331. // check row resize or select
  332. if (mouseMode == MouseMode.None)
  333. {
  334. float top = AbsTop;
  335. for (int y = 0; y < Rows.Count; y++)
  336. {
  337. float height = Rows[y].Height;
  338. top += height;
  339. if (point.X > AbsLeft && point.X < AbsRight && point.Y > top - 3 && point.Y < top + 3)
  340. {
  341. // row resize
  342. PointF pt = new PointF(e.x, e.y + 3);
  343. Point pt1 = GetAddressAtMousePoint(pt, false);
  344. Point pt2 = GetAddressAtMousePoint(pt, true);
  345. // check if we are in span
  346. if (pt1 == pt2)
  347. {
  348. mouseMode = MouseMode.ResizeRow;
  349. e.cursor = Cursors.HSplit;
  350. e.data = Rows[y];
  351. break;
  352. }
  353. }
  354. else if (point.X > AbsLeft - 8 && point.X < AbsLeft + 2 && point.Y > top - height && point.Y < top)
  355. {
  356. // row select
  357. mouseMode = MouseMode.SelectRow;
  358. e.cursor = curRightArrow;
  359. e.data = Rows[y];
  360. break;
  361. }
  362. }
  363. }
  364. }
  365. if (mouseMode != MouseMode.None)
  366. {
  367. e.handled = true;
  368. e.mode = WorkspaceMode2.Custom;
  369. }
  370. }
  371. else if (e.mode == WorkspaceMode2.Custom && e.button == MouseButtons.Left)
  372. {
  373. switch (mouseMode)
  374. {
  375. case MouseMode.SelectColumn:
  376. SetSelection(startSelectionPoint.X, 0,
  377. GetAddressAtMousePoint(new PointF(e.x, e.y), false).X, Rows.Count - 1);
  378. break;
  379. case MouseMode.SelectRow:
  380. SetSelection(0, startSelectionPoint.Y,
  381. Columns.Count - 1, GetAddressAtMousePoint(new PointF(e.x, e.y), false).Y);
  382. break;
  383. case MouseMode.SelectCell:
  384. Point pt = GetAddressAtMousePoint(new PointF(e.x, e.y), false);
  385. SetSelection(startSelectionPoint.X, startSelectionPoint.Y, pt.X, pt.Y);
  386. break;
  387. case MouseMode.ResizeColumn:
  388. TableColumn col = e.data as TableColumn;
  389. col.Width += e.delta.X;
  390. if ((e.modifierKeys & Keys.Control) != 0 && col.Index < ColumnCount - 1)
  391. {
  392. TableColumn nextCol = Columns[col.Index + 1];
  393. nextCol.Width -= e.delta.X;
  394. }
  395. if (col.Width <= 0)
  396. col.Width = 1;
  397. break;
  398. case MouseMode.ResizeRow:
  399. TableRow row = e.data as TableRow;
  400. row.Height += e.delta.Y;
  401. if ((e.modifierKeys & Keys.Control) != 0 && row.Index < RowCount - 1)
  402. {
  403. TableRow nextRow = Rows[row.Index + 1];
  404. nextRow.Height -= e.delta.Y;
  405. }
  406. if (row.Height <= 0)
  407. row.Height = 1;
  408. break;
  409. }
  410. }
  411. }
  412. /// <inheritdoc/>
  413. public override void HandleMouseUp(FRMouseEventArgs e)
  414. {
  415. base.HandleMouseUp(e);
  416. if (mouseMode == MouseMode.ResizeRow)
  417. {
  418. // update band's height
  419. if (Parent is BandBase)
  420. (Parent as BandBase).FixHeight();
  421. Report.Designer.SetModified(null, "Size", (e.data as TableRow).Name);
  422. }
  423. if (mouseMode == MouseMode.ResizeColumn)
  424. Report.Designer.SetModified(null, "Size", (e.data as TableColumn).Name);
  425. mouseMode = MouseMode.None;
  426. }
  427. /// <inheritdoc/>
  428. public override void OnAfterInsert(InsertFrom source)
  429. {
  430. CreateUniqueNames();
  431. }
  432. /// <inheritdoc/>
  433. public override void OnBeforeInsert(int flags)
  434. {
  435. Width = TableColumn.DefaultWidth * 5;
  436. Height = TableRow.DefaultHeight * 5;
  437. RowCount = 5;
  438. ColumnCount = 5;
  439. }
  440. #endregion Public Methods
  441. #region Internal Methods
  442. internal virtual ContextMenuBase GetCellContextMenu(TableCell cell)
  443. {
  444. return null;
  445. }
  446. internal virtual SmartTagBase GetCellSmartTag(TableCell cell)
  447. {
  448. return null;
  449. }
  450. internal virtual ContextMenuBase GetColumnContextMenu(TableColumn column)
  451. {
  452. return null;
  453. }
  454. internal virtual ContextMenuBase GetRowContextMenu(TableRow row)
  455. {
  456. return null;
  457. }
  458. internal Rectangle GetSelectionRect()
  459. {
  460. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  461. int minX = 1000;
  462. int minY = 1000;
  463. int maxX = 0;
  464. int maxY = 0;
  465. foreach (Base c in selection)
  466. {
  467. if (c is TableCell)
  468. {
  469. TableCell cell = c as TableCell;
  470. Point a = cell.Address;
  471. if (a.X < minX)
  472. minX = a.X;
  473. if (a.X > maxX)
  474. maxX = a.X;
  475. if (a.Y < minY)
  476. minY = a.Y;
  477. if (a.Y > maxY)
  478. maxY = a.Y;
  479. }
  480. }
  481. return new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
  482. }
  483. internal virtual void HandleCellDoubleClick(TableCell cell)
  484. {
  485. // do nothing
  486. }
  487. internal virtual string GetCellDisplayText(TableCell cell, string defaultText)
  488. {
  489. return defaultText;
  490. }
  491. internal virtual void ProvideCustomItems(TableCell cell, DataTreeView tree)
  492. {
  493. // does nothing
  494. }
  495. // fix table parent height on table change
  496. internal void FixParentHeight()
  497. {
  498. if (!IsDesigning)
  499. return;
  500. // get the table height. Height property may not be updated yet.
  501. float height = 0;
  502. foreach (TableRow row in Rows)
  503. height += row.Height;
  504. if (Top + height > (Parent as ComponentBase).Height)
  505. {
  506. (Parent as ComponentBase).Height = Top + height;
  507. (Report.Designer.ActiveReportTab.ActivePageDesigner as Design.PageDesigners.Page.ReportPageDesigner).Workspace.UpdateBands();
  508. }
  509. }
  510. #endregion Internal Methods
  511. #region Private Methods
  512. private void DrawDesign(FRPaintEventArgs e)
  513. {
  514. if (IsDesigning && IsSelected)
  515. {
  516. float m = Report.Designer.DpiMultiplier();
  517. e.Graphics.DrawImage(Report.Designer.GetImage(75), (int)(AbsLeft * e.ScaleX + 8 * m), (int)(AbsTop * e.ScaleY - 8 * m));
  518. }
  519. }
  520. private void DrawDesign_Borders(FRPaintEventArgs e)
  521. {
  522. if (IsDesigning)
  523. DrawCells(e, DrawDesignBorders);
  524. }
  525. private void DrawDesign_BordersRtl(FRPaintEventArgs e)
  526. {
  527. if (IsDesigning)
  528. DrawCellsRtl(e, DrawDesignBorders);
  529. }
  530. private void DrawDesign_SelectedCells(FRPaintEventArgs e)
  531. {
  532. if (IsDesigning && IsSelected)
  533. {
  534. DrawCells(e, DrawSelectedCells);
  535. DrawSelectedRowsColumns(e);
  536. }
  537. }
  538. private void DrawDesign_SelectedCellsRtl(FRPaintEventArgs e)
  539. {
  540. if (IsDesigning && IsSelected)
  541. {
  542. DrawCellsRtl(e, DrawSelectedCells);
  543. DrawSelectedRowsColumns(e);
  544. }
  545. }
  546. private void DrawDesignBorders(FRPaintEventArgs e, TableCell cell)
  547. {
  548. if (cell.Fill is SolidFill && (cell.Fill.IsTransparent ||
  549. (cell.Fill as SolidFill).Color == Color.White))
  550. {
  551. cell.DrawMarkers(e, MarkerStyle.Rectangle);
  552. }
  553. }
  554. private void DrawSelectedCells(FRPaintEventArgs e, TableCell cell)
  555. {
  556. if (Report.Designer.SelectedObjects.Contains(cell))
  557. {
  558. Brush brush = e.Cache.GetBrush(Color.FromArgb(128, SystemColors.Highlight));
  559. e.Graphics.FillRectangle(brush, cell.AbsLeft * e.ScaleX, cell.AbsTop * e.ScaleY,
  560. cell.Width * e.ScaleX, cell.Height * e.ScaleY);
  561. }
  562. }
  563. private void DrawSelectedRowsColumns(FRPaintEventArgs e)
  564. {
  565. IGraphics g = e.Graphics;
  566. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  567. Brush brush = e.Cache.GetBrush(Color.FromArgb(128, SystemColors.Highlight));
  568. foreach (Base c in selection)
  569. {
  570. if (c is TableRow)
  571. {
  572. TableRow row = c as TableRow;
  573. g.FillRectangle(brush, AbsLeft * e.ScaleX, (row.Top + AbsTop) * e.ScaleY,
  574. Width * e.ScaleX, row.Height * e.ScaleY);
  575. }
  576. else if (c is TableColumn)
  577. {
  578. TableColumn col = c as TableColumn;
  579. g.FillRectangle(brush, (col.Left + AbsLeft) * e.ScaleX, AbsTop * e.ScaleY,
  580. col.Width * e.ScaleX, Height * e.ScaleY);
  581. }
  582. }
  583. }
  584. private Point GetAddressAtMousePoint(PointF pt, bool checkSpan)
  585. {
  586. Point result = new Point();
  587. float left = AbsLeft;
  588. for (int x = 0; x < Columns.Count; x++)
  589. {
  590. float width = Columns[x].Width;
  591. if (pt.X >= left && pt.X < left + width)
  592. {
  593. result.X = x;
  594. break;
  595. }
  596. left += width;
  597. }
  598. if (pt.X >= AbsRight)
  599. result.X = Columns.Count - 1;
  600. float top = AbsTop;
  601. for (int y = 0; y < Rows.Count; y++)
  602. {
  603. float height = Rows[y].Height;
  604. if (pt.Y >= top && pt.Y < top + height)
  605. {
  606. result.Y = y;
  607. break;
  608. }
  609. top += height;
  610. }
  611. if (pt.Y >= AbsBottom)
  612. result.Y = Rows.Count - 1;
  613. if (checkSpan)
  614. {
  615. List<Rectangle> spans = GetSpanList();
  616. foreach (Rectangle span in spans)
  617. {
  618. if (span.Contains(result))
  619. {
  620. result = span.Location;
  621. break;
  622. }
  623. }
  624. }
  625. return result;
  626. }
  627. private void SetSelection(int x1, int y1, int x2, int y2)
  628. {
  629. Rectangle rect = new Rectangle();
  630. rect.X = x1 < x2 ? x1 : x2;
  631. rect.Y = y1 < y2 ? y1 : y2;
  632. rect.Width = (int)Math.Abs(x1 - x2) + 1;
  633. rect.Height = (int)Math.Abs(y1 - y2) + 1;
  634. SelectedObjectCollection selection = Report.Designer.SelectedObjects;
  635. selection.Clear();
  636. if (mouseMode == MouseMode.SelectRow)
  637. {
  638. for (int y = rect.Top; y < rect.Bottom; y++)
  639. {
  640. selection.Add(Rows[y]);
  641. }
  642. }
  643. else if (mouseMode == MouseMode.SelectColumn)
  644. {
  645. for (int x = rect.Left; x < rect.Right; x++)
  646. {
  647. selection.Add(Columns[x]);
  648. }
  649. }
  650. else if (mouseMode == MouseMode.SelectCell)
  651. {
  652. List<Rectangle> spans = GetSpanList();
  653. // widen selection if spans are inside
  654. foreach (Rectangle span in spans)
  655. {
  656. if (rect.IntersectsWith(span))
  657. {
  658. if (span.X < rect.X)
  659. {
  660. rect.Width += rect.X - span.X;
  661. rect.X = span.X;
  662. }
  663. if (span.Right > rect.Right)
  664. rect.Width += span.Right - rect.Right;
  665. if (span.Y < rect.Y)
  666. {
  667. rect.Height += rect.Y - span.Y;
  668. rect.Y = span.Y;
  669. }
  670. if (span.Bottom > rect.Bottom)
  671. rect.Height += span.Bottom - rect.Bottom;
  672. }
  673. }
  674. for (int x = rect.Left; x < rect.Right; x++)
  675. {
  676. for (int y = rect.Top; y < rect.Bottom; y++)
  677. {
  678. selection.Add(this[x, y]);
  679. }
  680. }
  681. }
  682. }
  683. #endregion Private Methods
  684. }
  685. }