LinkLabel.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004-2005 Novell, Inc.
  21. //
  22. // Authors:
  23. // Jordi Mas i Hernandez, [email protected]
  24. //
  25. // Based on work by:
  26. // Daniel Carrera, [email protected] (stubbed out)
  27. // Jaak Simm ([email protected]) (stubbed out)
  28. //
  29. // COMPLETE
  30. using System.ComponentModel;
  31. using System.Collections;
  32. using System.Drawing;
  33. using System.Drawing.Drawing2D;
  34. namespace System.Windows.Forms
  35. {
  36. [DefaultEvent("LinkClicked")]
  37. public class LinkLabel : Label, IButtonControl
  38. {
  39. /* Encapsulates a piece of text (regular or link)*/
  40. internal class Piece
  41. {
  42. public string text;
  43. public int start;
  44. public int end;
  45. public LinkLabel.Link link; // Empty link indicates regular text
  46. public Rectangle rect;
  47. public bool clicked;
  48. public bool focused;
  49. public Piece ()
  50. {
  51. start = end = 0;
  52. link = null;
  53. clicked = false;
  54. focused = false;
  55. }
  56. }
  57. private Color active_link;
  58. private Color disabled_link;
  59. private Color link_color;
  60. private Color visited_color;
  61. private LinkArea link_area;
  62. private LinkBehavior link_behavior;
  63. private LinkCollection link_collection;
  64. private bool link_visited;
  65. private bool link_click;
  66. internal Piece[] pieces;
  67. internal int num_pieces;
  68. internal Font link_font;
  69. private Cursor override_cursor;
  70. private DialogResult dialog_result;
  71. #region Events
  72. public event LinkLabelLinkClickedEventHandler LinkClicked;
  73. #endregion // Events
  74. public LinkLabel ()
  75. {
  76. LinkArea = new LinkArea (0, -1);
  77. link_behavior = LinkBehavior.SystemDefault;
  78. link_visited = false;
  79. link_click = false;
  80. pieces = null;
  81. num_pieces = 0;
  82. link_font = null;
  83. ActiveLinkColor = Color.Red;
  84. DisabledLinkColor = ThemeEngine.Current.ColorGrayText;
  85. LinkColor = Color.FromArgb (255, 0, 0, 255);
  86. VisitedLinkColor = Color.FromArgb (255, 128, 0, 128);
  87. SetStyle (ControlStyles.Selectable, false);
  88. SetStyle (ControlStyles.Opaque, true);
  89. }
  90. #region Public Properties
  91. public Color ActiveLinkColor {
  92. get { return active_link;}
  93. set {
  94. if (active_link == value)
  95. return;
  96. active_link = value;
  97. Refresh ();
  98. }
  99. }
  100. public Color DisabledLinkColor {
  101. get { return disabled_link;}
  102. set {
  103. if (disabled_link == value)
  104. return;
  105. disabled_link = value;
  106. Refresh ();
  107. }
  108. }
  109. public Color LinkColor {
  110. get { return link_color;}
  111. set {
  112. if (link_color == value)
  113. return;
  114. link_color = value;
  115. Refresh ();
  116. }
  117. }
  118. public Color VisitedLinkColor {
  119. get { return visited_color;}
  120. set {
  121. if (visited_color == value)
  122. return;
  123. visited_color = value;
  124. Refresh ();
  125. }
  126. }
  127. [Localizable (true)]
  128. [Editor ("System.Windows.Forms.Design.LinkAreaEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
  129. public LinkArea LinkArea {
  130. get { return link_area;}
  131. set {
  132. if (value.Start <0 || value.Length < -1)
  133. throw new ArgumentException ();
  134. if (!value.IsEmpty)
  135. Links.Add (value.Start, value.Length);
  136. link_area = value;
  137. Refresh ();
  138. }
  139. }
  140. [DefaultValue (LinkBehavior.SystemDefault)]
  141. public LinkBehavior LinkBehavior {
  142. get { return link_behavior;}
  143. set {
  144. if (link_behavior == value)
  145. return;
  146. link_behavior = value;
  147. Refresh ();
  148. }
  149. }
  150. [Browsable (false)]
  151. [EditorBrowsable (EditorBrowsableState.Advanced)]
  152. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  153. public LinkLabel.LinkCollection Links {
  154. get {
  155. if (link_collection == null)
  156. link_collection = new LinkCollection (this);
  157. return link_collection;
  158. }
  159. }
  160. [DefaultValue (false)]
  161. public bool LinkVisited {
  162. get { return link_visited;}
  163. set {
  164. if (link_visited == value)
  165. return;
  166. link_visited = value;
  167. Refresh ();
  168. }
  169. }
  170. protected Cursor OverrideCursor {
  171. get { return override_cursor;}
  172. set { override_cursor = value;}
  173. }
  174. [RefreshProperties(RefreshProperties.Repaint)]
  175. public override string Text {
  176. get { return base.Text; }
  177. set {
  178. if (base.Text == value)
  179. return;
  180. base.Text = value;
  181. CreateLinkPieces ();
  182. }
  183. }
  184. #endregion // Public Properties
  185. DialogResult IButtonControl.DialogResult {
  186. get { return dialog_result; }
  187. set { dialog_result = value; }
  188. }
  189. void IButtonControl.NotifyDefault (bool value)
  190. {
  191. }
  192. void IButtonControl.PerformClick ()
  193. {
  194. }
  195. #region Public Methods
  196. protected override AccessibleObject CreateAccessibilityInstance ()
  197. {
  198. return base.CreateAccessibilityInstance();
  199. }
  200. protected override void CreateHandle ()
  201. {
  202. base.CreateHandle ();
  203. CreateLinkFont ();
  204. CreateLinkPieces ();
  205. }
  206. protected override void OnEnabledChanged (EventArgs e)
  207. {
  208. base.OnEnabledChanged (e);
  209. Refresh ();
  210. }
  211. protected override void OnFontChanged (EventArgs e)
  212. {
  213. base.OnFontChanged (e);
  214. CreateLinkFont ();
  215. CreateLinkPieces ();
  216. }
  217. protected override void OnGotFocus (EventArgs e)
  218. {
  219. base.OnGotFocus (e);
  220. // Set focus to the first enabled link piece
  221. for (int i = 0; i < num_pieces; i++) {
  222. if (pieces[i].link != null && pieces[i].link.Enabled) {
  223. pieces[i].focused = true;
  224. Invalidate (pieces[i].rect);
  225. break;
  226. }
  227. }
  228. }
  229. protected override void OnKeyDown (KeyEventArgs e)
  230. {
  231. base.OnKeyDown(e);
  232. // Set focus to the next link piece
  233. if (e.KeyCode == Keys.Tab || e.KeyCode == Keys.Right) {
  234. for (int i = 0; i < num_pieces; i++) {
  235. if (pieces[i].focused) {
  236. pieces[i].focused = false;
  237. Invalidate (pieces[i].rect);
  238. for (int n = i + 1; n < num_pieces; n++) {
  239. if (pieces[n].link != null && pieces[n].link.Enabled) {
  240. pieces[n].focused = true;
  241. e.Handled = true;
  242. Invalidate (pieces[n].rect);
  243. return;
  244. }
  245. }
  246. }
  247. }
  248. } else if (e.KeyCode == Keys.Return) {
  249. for (int i = 0; i < num_pieces; i++) {
  250. if (pieces[i].focused && pieces[i].link != null) {
  251. OnLinkClicked (new LinkLabelLinkClickedEventArgs (pieces[i].link));
  252. break;
  253. }
  254. }
  255. }
  256. }
  257. protected virtual void OnLinkClicked (LinkLabelLinkClickedEventArgs e)
  258. {
  259. if (LinkClicked != null)
  260. LinkClicked (this, e);
  261. }
  262. protected override void OnLostFocus (EventArgs e)
  263. {
  264. base.OnLostFocus (e);
  265. // Clean focus in link pieces
  266. for (int i = 0; i < num_pieces; i++) {
  267. if (pieces[i].focused) {
  268. pieces[i].focused = false;
  269. }
  270. }
  271. Refresh ();
  272. }
  273. protected override void OnMouseDown (MouseEventArgs e)
  274. {
  275. if (!Enabled) return;
  276. base.OnMouseDown (e);
  277. this.Capture = true;
  278. for (int i = 0; i < num_pieces; i++) {
  279. if (pieces[i].rect.Contains (e.X, e.Y)) {
  280. if (pieces[i].link!= null) {
  281. pieces[i].clicked = true;
  282. Invalidate (pieces[i].rect);
  283. }
  284. break;
  285. }
  286. }
  287. }
  288. protected override void OnMouseLeave(EventArgs e)
  289. {
  290. if (!Enabled) return;
  291. base.OnMouseLeave (e);
  292. }
  293. protected override void OnMouseMove (MouseEventArgs e)
  294. {
  295. base.OnMouseMove (e);
  296. Link link = PointInLink (e.X, e.Y);
  297. if (link == null) {
  298. Cursor = Cursors.Default;
  299. bool changed = false;
  300. if (link_behavior == LinkBehavior.HoverUnderline) {
  301. for (int i = 0; i < Links.Count; i++) {
  302. if (Links[i].Hoovered == true) {
  303. changed = true;
  304. Links[i].Hoovered = false;
  305. }
  306. }
  307. if (changed == true)
  308. Refresh ();
  309. }
  310. return;
  311. }
  312. if (link_behavior == LinkBehavior.HoverUnderline) {
  313. if (link.Hoovered != true) {
  314. link.Hoovered = true;
  315. Refresh ();
  316. }
  317. }
  318. Cursor = Cursors.Hand;
  319. }
  320. protected override void OnMouseUp (MouseEventArgs e)
  321. {
  322. if (!Enabled) return;
  323. base.OnMouseUp (e);
  324. this.Capture = false;
  325. for (int i = 0; i < num_pieces; i++) {
  326. if (pieces[i].link!= null && pieces[i].clicked == true) {
  327. OnLinkClicked (new LinkLabelLinkClickedEventArgs (pieces[i].link));
  328. pieces[i].clicked = false;
  329. Invalidate (pieces[i].rect);
  330. break;
  331. }
  332. }
  333. }
  334. protected override void OnPaint (PaintEventArgs pevent)
  335. {
  336. ThemeEngine.Current.DrawLinkLabel (pevent.Graphics, pevent.ClipRectangle, this);
  337. DrawImage (pevent.Graphics, Image, ClientRectangle, image_align);
  338. // Do not call base.OnPaint since it's the Label class
  339. }
  340. protected override void OnPaintBackground (PaintEventArgs e)
  341. {
  342. base.OnPaintBackground (e);
  343. }
  344. protected override void OnTextAlignChanged (EventArgs e)
  345. {
  346. base.OnTextAlignChanged (e);
  347. CreateLinkPieces ();
  348. }
  349. protected override void OnTextChanged (EventArgs e)
  350. {
  351. base.OnTextChanged (e);
  352. }
  353. protected Link PointInLink (int x, int y)
  354. {
  355. for (int i = 0; i < num_pieces; i++) {
  356. if (pieces[i].rect.Contains (x,y) && pieces[i].link != null)
  357. return pieces[i].link;
  358. }
  359. return null;
  360. }
  361. protected override bool ProcessDialogKey (Keys keyData)
  362. {
  363. return base.ProcessDialogKey (keyData);
  364. }
  365. protected override void Select (bool directed, bool forward)
  366. {
  367. base.Select (directed, forward);
  368. }
  369. protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
  370. {
  371. base.SetBoundsCore (x, y, width, height, specified);
  372. }
  373. protected override void WndProc (ref Message m)
  374. {
  375. base.WndProc (ref m);
  376. }
  377. #endregion //Public Methods
  378. #region Private Methods
  379. internal void CreateLinkPieces ()
  380. {
  381. if (Links.Count == 0 || IsHandleCreated == false || Text.Length == 0)
  382. return;
  383. int cur_piece = 0;
  384. num_pieces = 0;
  385. if (Links.Count == 1 && Links[0].Start == 0 && Links[0].Length == -1) {
  386. Links[0].Length = Text.Length;
  387. }
  388. pieces = new Piece [(Links.Count * 2) + 1];
  389. pieces[cur_piece] = new Piece();
  390. pieces[cur_piece].start = 0;
  391. for (int i = 0; i < Text.Length; i++) { /* Every char on the text*/
  392. for (int l = 0; l < Links.Count; l++) { /* Every link that we know of*/
  393. if (Links[l].Start == i) {
  394. if (i > 0) {
  395. /*Push prev. regular text*/
  396. pieces[cur_piece].end = i;
  397. pieces[cur_piece].text = Text.Substring (pieces[cur_piece].start,
  398. pieces[cur_piece].end - pieces[cur_piece].start);
  399. cur_piece++;
  400. /* New link*/
  401. pieces[cur_piece] = new Piece ();
  402. }
  403. int end;
  404. if (Links[l].Start + Links[l].Length > Text.Length) {
  405. end = Text.Length - Links[l].Start;
  406. }
  407. else {
  408. end = Links[l].Length;
  409. }
  410. pieces[cur_piece].start = Links[l].Start;
  411. pieces[cur_piece].end = Links[l].Start + end;
  412. pieces[cur_piece].link = Links[l];
  413. pieces[cur_piece].text = Text.Substring (pieces[cur_piece].start, end);
  414. cur_piece++; /* Push link*/
  415. pieces[cur_piece] = new Piece();
  416. i+= Links[l].Length;
  417. pieces[cur_piece].start = i;
  418. }
  419. }
  420. }
  421. if (pieces[cur_piece].end == 0 && pieces[cur_piece].start < Text.Length) {
  422. pieces[cur_piece].end = Text.Length;
  423. pieces[cur_piece].text = Text.Substring (pieces[cur_piece].start, pieces[cur_piece].end - pieces[cur_piece].start);
  424. cur_piece++;
  425. }
  426. num_pieces = cur_piece;
  427. CharacterRange[] charRanges = new CharacterRange [num_pieces];
  428. for (int i = 0; i < num_pieces; i++)
  429. charRanges[i] = new CharacterRange (pieces[i].start, pieces[i].end - pieces[i].start);
  430. Region[] charRegions = new Region [num_pieces];
  431. string_format.SetMeasurableCharacterRanges (charRanges);
  432. // BUG: This sizes do not match the ones used later when drawing
  433. charRegions = DeviceContext.MeasureCharacterRanges (Text, link_font, ClientRectangle, string_format);
  434. RectangleF rect;
  435. for (int i = 0; i < num_pieces; i++) {
  436. rect = charRegions[i].GetBounds (DeviceContext);
  437. pieces[i].rect = Rectangle.Ceiling (rect);
  438. charRegions[i].Dispose ();
  439. }
  440. if (Visible && IsHandleCreated)
  441. Refresh ();
  442. }
  443. /* Check if the links overlap */
  444. internal void CheckLinks ()
  445. {
  446. for (int i = 0; i < Links.Count; i++) {
  447. for (int l = 0; l < Links.Count; l++) {
  448. if (i==l) continue;
  449. if (((Links[i].Start + Links[i].Length) >= Links[l].Start &&
  450. Links[i].Start + Links[i].Length <= Links[l].Start + Links[l].Length) ||
  451. (Links[i].Start >= Links[l].Start &&
  452. Links[i].Start <= Links[l].Start + Links[l].Length))
  453. throw new InvalidOperationException ("Overlapping link regions.");
  454. }
  455. }
  456. }
  457. internal Font GetPieceFont (Piece piece)
  458. {
  459. switch (link_behavior) {
  460. case LinkBehavior.AlwaysUnderline:
  461. case LinkBehavior.SystemDefault: // Depends on IE configuration
  462. {
  463. if (piece.link == null) {
  464. return Font;
  465. } else {
  466. return link_font;
  467. }
  468. }
  469. case LinkBehavior.HoverUnderline:
  470. {
  471. if (piece.link != null && piece.link.Hoovered) {
  472. return link_font;
  473. } else {
  474. return Font;
  475. }
  476. }
  477. case LinkBehavior.NeverUnderline:
  478. default:
  479. return Font;
  480. }
  481. }
  482. internal Color GetLinkColor (Piece piece, int i)
  483. {
  484. Color color;
  485. if (Enabled == false ||
  486. (piece.link != null && piece.link.Enabled == false))
  487. color = DisabledLinkColor;
  488. else
  489. if (piece.clicked == true)
  490. color = ActiveLinkColor;
  491. else
  492. if ((LinkVisited == true && i == 0) ||
  493. (piece.link != null && piece.link.Visited == true))
  494. color = VisitedLinkColor;
  495. else
  496. color = LinkColor;
  497. return color;
  498. }
  499. private void CreateLinkFont ()
  500. {
  501. if (link_font != null)
  502. link_font.Dispose ();
  503. link_font = new Font (Font.FontFamily, Font.Size, Font.Style | FontStyle.Underline,
  504. Font.Unit);
  505. }
  506. #endregion // Private Methods
  507. //
  508. // System.Windows.Forms.LinkLabel.Link
  509. //
  510. public class Link
  511. {
  512. private bool enabled;
  513. internal int length;
  514. private object linkData;
  515. private int start;
  516. private bool visited;
  517. private LinkLabel owner;
  518. private bool hoovered;
  519. internal Link ()
  520. {
  521. enabled = true;
  522. visited = false;
  523. length = start = 0;
  524. linkData = null;
  525. owner = null;
  526. }
  527. internal Link (LinkLabel owner)
  528. {
  529. enabled = true;
  530. visited = false;
  531. length = start = 0;
  532. linkData = null;
  533. this.owner = owner;
  534. }
  535. public bool Enabled {
  536. get { return enabled; }
  537. set {
  538. if (enabled == value)
  539. return;
  540. enabled = value;
  541. if (owner != null)
  542. owner.Refresh ();
  543. }
  544. }
  545. public int Length {
  546. get {
  547. if (length == -1) {
  548. return owner.Text.Length;
  549. }
  550. return length;
  551. }
  552. set {
  553. if (length == value)
  554. return;
  555. length = value;
  556. if (owner != null)
  557. owner.CreateLinkPieces ();
  558. }
  559. }
  560. public object LinkData {
  561. get { return linkData; }
  562. set { linkData = value; }
  563. }
  564. public int Start {
  565. get { return start; }
  566. set {
  567. if (start == value)
  568. return;
  569. start = value;
  570. if (owner != null)
  571. owner.CreateLinkPieces ();
  572. }
  573. }
  574. public bool Visited {
  575. get { return visited; }
  576. set {
  577. if (visited == value)
  578. return;
  579. visited = value;
  580. if (owner != null)
  581. owner.Refresh ();
  582. }
  583. }
  584. internal bool Hoovered {
  585. get { return hoovered; }
  586. set { hoovered = value; }
  587. }
  588. }
  589. //
  590. // System.Windows.Forms.LinkLabel.Link
  591. //
  592. public class LinkCollection : IList, ICollection, IEnumerable
  593. {
  594. private LinkLabel owner;
  595. private ArrayList collection = new ArrayList();
  596. public LinkCollection (LinkLabel owner)
  597. {
  598. if (owner==null)
  599. throw new ArgumentNullException ();
  600. this.owner = owner;
  601. }
  602. [Browsable (false)]
  603. public int Count {
  604. get { return collection.Count; }
  605. }
  606. public bool IsReadOnly {
  607. get { return false; }
  608. }
  609. public virtual LinkLabel.Link this[int index] {
  610. get {
  611. if (index < 0 || index >= Count)
  612. throw new ArgumentOutOfRangeException();
  613. return (LinkLabel.Link) collection[index];
  614. }
  615. set {
  616. if (index < 0 || index >= Count)
  617. throw new ArgumentOutOfRangeException();
  618. collection[index] = value;
  619. }
  620. }
  621. public Link Add (int start, int length)
  622. {
  623. return Add (start, length, null);
  624. }
  625. public Link Add (int start, int length, object o)
  626. {
  627. Link link = new Link (owner);
  628. int idx;
  629. if (Count == 1 && this[0].Start == 0
  630. && this[0].length == -1) {
  631. Clear ();
  632. }
  633. link.Length = length;
  634. link.Start = start;
  635. link.LinkData = o;
  636. idx = collection.Add (link);
  637. owner.CheckLinks ();
  638. owner.CreateLinkPieces ();
  639. return (Link) collection[idx];
  640. }
  641. public virtual void Clear ()
  642. {
  643. collection.Clear();
  644. owner.CreateLinkPieces ();
  645. }
  646. public bool Contains (LinkLabel.Link link)
  647. {
  648. return collection.Contains (link);
  649. }
  650. public IEnumerator GetEnumerator ()
  651. {
  652. return collection.GetEnumerator ();
  653. }
  654. public int IndexOf (LinkLabel.Link link)
  655. {
  656. return collection.IndexOf (link);
  657. }
  658. public void Remove (LinkLabel.Link value)
  659. {
  660. collection.Remove (value);
  661. owner.CreateLinkPieces ();
  662. }
  663. public void RemoveAt (int index)
  664. {
  665. if (index >= Count)
  666. throw new ArgumentOutOfRangeException ("Invalid value for array index");
  667. collection.Remove (collection[index]);
  668. owner.CreateLinkPieces ();
  669. }
  670. bool IList.IsFixedSize {
  671. get {return false;}
  672. }
  673. object IList.this[int index] {
  674. get { return collection[index]; }
  675. set { collection[index] = value; }
  676. }
  677. object ICollection.SyncRoot {
  678. get {return this;}
  679. }
  680. bool ICollection.IsSynchronized {
  681. get {return false;}
  682. }
  683. void ICollection.CopyTo (Array dest, int index)
  684. {
  685. collection.CopyTo (dest, index);
  686. }
  687. int IList.Add (object control)
  688. {
  689. int idx = collection.Add (control);
  690. owner.CheckLinks ();
  691. owner.CreateLinkPieces ();
  692. return idx;
  693. }
  694. bool IList.Contains (object control)
  695. {
  696. return collection.Contains (control);
  697. }
  698. int IList.IndexOf (object control)
  699. {
  700. return collection.IndexOf (control);
  701. }
  702. void IList.Insert (int index, object value)
  703. {
  704. collection.Insert (index, value);
  705. owner.CheckLinks ();
  706. owner.CreateLinkPieces ();
  707. }
  708. void IList.Remove (object control)
  709. {
  710. collection.Remove (control);
  711. owner.CreateLinkPieces ();
  712. }
  713. }
  714. }
  715. }