PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListViewItem.cs

https://bitbucket.org/danipen/mono
C# | 1637 lines | 1307 code | 266 blank | 64 comment | 254 complexity | 68bf3f9aed5a03919190033ba156f698 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  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 Novell, Inc. (http://www.novell.com)
  21. //
  22. // Author:
  23. // Ravindra (rkumar@novell.com)
  24. // Mike Kestner <mkestner@novell.com>
  25. // Daniel Nauck (dna(at)mono-project(dot)de)
  26. using System.Collections;
  27. using System.ComponentModel;
  28. using System.Drawing;
  29. using System.Runtime.Serialization;
  30. namespace System.Windows.Forms
  31. {
  32. [DefaultProperty ("Text")]
  33. [DesignTimeVisible (false)]
  34. [Serializable]
  35. [ToolboxItem (false)]
  36. [TypeConverter (typeof (ListViewItemConverter))]
  37. public class ListViewItem : ICloneable, ISerializable
  38. {
  39. #region Instance Variables
  40. private int image_index = -1;
  41. private bool is_checked = false;
  42. private int state_image_index = -1;
  43. private ListViewSubItemCollection sub_items;
  44. private object tag;
  45. private bool use_item_style = true;
  46. int display_index = -1; // actual position in ListView
  47. private ListViewGroup group = null;
  48. private string name = String.Empty;
  49. private string image_key = String.Empty;
  50. string tooltip_text = String.Empty;
  51. int indent_count;
  52. Point position = new Point (-1, -1); // cached to mimic .Net behaviour
  53. Rectangle bounds = Rectangle.Empty;
  54. Rectangle checkbox_rect; // calculated by CalcListViewItem method
  55. Rectangle icon_rect;
  56. Rectangle item_rect;
  57. Rectangle label_rect;
  58. ListView owner;
  59. Font font;
  60. Font hot_font; // cached font for hot tracking
  61. bool selected;
  62. internal int row;
  63. internal int col;
  64. #region UIA Framework: Methods, Properties and Events
  65. internal event EventHandler UIATextChanged;
  66. internal event LabelEditEventHandler UIASubItemTextChanged;
  67. internal void OnUIATextChanged ()
  68. {
  69. if (UIATextChanged != null)
  70. UIATextChanged (this, EventArgs.Empty);
  71. }
  72. internal void OnUIASubItemTextChanged (LabelEditEventArgs args)
  73. {
  74. //If our index is 0 we also generate TextChanged for the ListViewItem
  75. //because ListViewItem.Text is the same as ListViewItem.SubItems [0].Text
  76. if (args.Item == 0)
  77. OnUIATextChanged ();
  78. if (UIASubItemTextChanged != null)
  79. UIASubItemTextChanged (this, args);
  80. }
  81. #endregion // UIA Framework: Methods, Properties and Events
  82. #endregion Instance Variables
  83. #region Public Constructors
  84. public ListViewItem () : this (string.Empty)
  85. {
  86. }
  87. public ListViewItem (string text) : this (text, -1)
  88. {
  89. }
  90. public ListViewItem (string [] items) : this (items, -1)
  91. {
  92. }
  93. public ListViewItem (ListViewItem.ListViewSubItem [] subItems, int imageIndex)
  94. {
  95. this.sub_items = new ListViewSubItemCollection (this, null);
  96. for (int i = 0; i < subItems.Length; i++)
  97. sub_items.Add (subItems [i]);
  98. this.image_index = imageIndex;
  99. }
  100. public ListViewItem (string text, int imageIndex)
  101. {
  102. this.image_index = imageIndex;
  103. this.sub_items = new ListViewSubItemCollection (this, text);
  104. }
  105. public ListViewItem (string [] items, int imageIndex)
  106. {
  107. this.sub_items = new ListViewSubItemCollection (this, null);
  108. if (items != null) {
  109. for (int i = 0; i < items.Length; i++)
  110. sub_items.Add (new ListViewSubItem (this, items [i]));
  111. }
  112. this.image_index = imageIndex;
  113. }
  114. public ListViewItem (string [] items, int imageIndex, Color foreColor,
  115. Color backColor, Font font) : this (items, imageIndex)
  116. {
  117. ForeColor = foreColor;
  118. BackColor = backColor;
  119. this.font = font;
  120. }
  121. public ListViewItem(string[] items, string imageKey) : this(items)
  122. {
  123. this.ImageKey = imageKey;
  124. }
  125. public ListViewItem(string text, string imageKey) : this(text)
  126. {
  127. this.ImageKey = imageKey;
  128. }
  129. public ListViewItem(ListViewSubItem[] subItems, string imageKey)
  130. {
  131. this.sub_items = new ListViewSubItemCollection (this, null);
  132. for (int i = 0; i < subItems.Length; i++)
  133. this.sub_items.Add (subItems [i]);
  134. this.ImageKey = imageKey;
  135. }
  136. public ListViewItem(string[] items, string imageKey, Color foreColor,
  137. Color backColor, Font font) : this(items, imageKey)
  138. {
  139. ForeColor = foreColor;
  140. BackColor = backColor;
  141. this.font = font;
  142. }
  143. public ListViewItem(ListViewGroup group) : this()
  144. {
  145. Group = group;
  146. }
  147. public ListViewItem(string text, ListViewGroup group) : this(text)
  148. {
  149. Group = group;
  150. }
  151. public ListViewItem(string[] items, ListViewGroup group) : this(items)
  152. {
  153. Group = group;
  154. }
  155. public ListViewItem(ListViewSubItem[] subItems, int imageIndex, ListViewGroup group)
  156. : this(subItems, imageIndex)
  157. {
  158. Group = group;
  159. }
  160. public ListViewItem(ListViewSubItem[] subItems, string imageKey, ListViewGroup group)
  161. : this(subItems, imageKey)
  162. {
  163. Group = group;
  164. }
  165. public ListViewItem(string text, int imageIndex, ListViewGroup group)
  166. : this(text, imageIndex)
  167. {
  168. Group = group;
  169. }
  170. public ListViewItem(string text, string imageKey, ListViewGroup group)
  171. : this(text, imageKey)
  172. {
  173. Group = group;
  174. }
  175. public ListViewItem(string[] items, int imageIndex, ListViewGroup group)
  176. : this(items, imageIndex)
  177. {
  178. Group = group;
  179. }
  180. public ListViewItem(string[] items, string imageKey, ListViewGroup group)
  181. : this(items, imageKey)
  182. {
  183. Group = group;
  184. }
  185. public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor,
  186. Font font, ListViewGroup group)
  187. : this(items, imageIndex, foreColor, backColor, font)
  188. {
  189. Group = group;
  190. }
  191. public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor,
  192. Font font, ListViewGroup group)
  193. : this(items, imageKey, foreColor, backColor, font)
  194. {
  195. Group = group;
  196. }
  197. #endregion // Public Constructors
  198. protected ListViewItem (SerializationInfo info, StreamingContext context)
  199. {
  200. Deserialize (info, context);
  201. }
  202. #region Public Instance Properties
  203. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  204. public Color BackColor {
  205. get {
  206. if (sub_items.Count > 0)
  207. return sub_items[0].BackColor;
  208. if (owner != null)
  209. return owner.BackColor;
  210. return ThemeEngine.Current.ColorWindow;
  211. }
  212. set { SubItems [0].BackColor = value; }
  213. }
  214. [Browsable (false)]
  215. public Rectangle Bounds {
  216. get {
  217. return GetBounds (ItemBoundsPortion.Entire);
  218. }
  219. }
  220. [DefaultValue (false)]
  221. [RefreshProperties (RefreshProperties.Repaint)]
  222. public bool Checked {
  223. get { return is_checked; }
  224. set {
  225. if (is_checked == value)
  226. return;
  227. if (owner != null) {
  228. CheckState current_value = is_checked ? CheckState.Checked : CheckState.Unchecked;
  229. CheckState new_value = value ? CheckState.Checked : CheckState.Unchecked;
  230. ItemCheckEventArgs icea = new ItemCheckEventArgs (Index,
  231. new_value, current_value);
  232. owner.OnItemCheck (icea);
  233. if (new_value != current_value) {
  234. // force re-population of list
  235. owner.CheckedItems.Reset ();
  236. is_checked = new_value == CheckState.Checked;
  237. Invalidate ();
  238. ItemCheckedEventArgs args = new ItemCheckedEventArgs (this);
  239. owner.OnItemChecked (args);
  240. }
  241. } else
  242. is_checked = value;
  243. }
  244. }
  245. [Browsable (false)]
  246. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  247. public bool Focused {
  248. get {
  249. if (owner == null)
  250. return false;
  251. // In virtual mode the checks are always done using indexes
  252. if (owner.VirtualMode)
  253. return Index == owner.focused_item_index;
  254. // Light check
  255. return owner.FocusedItem == this;
  256. }
  257. set {
  258. if (owner == null)
  259. return;
  260. if (Focused == value)
  261. return;
  262. ListViewItem prev_focused_item = owner.FocusedItem;
  263. if (prev_focused_item != null)
  264. prev_focused_item.UpdateFocusedState ();
  265. owner.focused_item_index = value ? Index : -1;
  266. if (value)
  267. owner.OnUIAFocusedItemChanged ();
  268. UpdateFocusedState ();
  269. }
  270. }
  271. [Localizable (true)]
  272. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  273. public Font Font {
  274. get {
  275. if (font != null)
  276. return font;
  277. else if (owner != null)
  278. return owner.Font;
  279. return ThemeEngine.Current.DefaultFont;
  280. }
  281. set {
  282. if (font == value)
  283. return;
  284. font = value;
  285. hot_font = null;
  286. if (owner != null)
  287. Layout ();
  288. Invalidate ();
  289. }
  290. }
  291. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  292. public Color ForeColor {
  293. get {
  294. if (sub_items.Count > 0)
  295. return sub_items[0].ForeColor;
  296. if (owner != null)
  297. return owner.ForeColor;
  298. return ThemeEngine.Current.ColorWindowText;
  299. }
  300. set { SubItems [0].ForeColor = value; }
  301. }
  302. [DefaultValue (-1)]
  303. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  304. [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
  305. typeof (System.Drawing.Design.UITypeEditor))]
  306. [Localizable (true)]
  307. [RefreshProperties (RefreshProperties.Repaint)]
  308. [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
  309. public int ImageIndex {
  310. get { return image_index; }
  311. set {
  312. if (value < -1)
  313. throw new ArgumentException ("Invalid ImageIndex. It must be greater than or equal to -1.");
  314. image_index = value;
  315. image_key = String.Empty;
  316. if (owner != null)
  317. Layout ();
  318. Invalidate ();
  319. }
  320. }
  321. [DefaultValue ("")]
  322. [LocalizableAttribute (true)]
  323. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  324. [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
  325. typeof (System.Drawing.Design.UITypeEditor))]
  326. [RefreshProperties (RefreshProperties.Repaint)]
  327. [TypeConverter (typeof (ImageKeyConverter))]
  328. public string ImageKey {
  329. get {
  330. return image_key;
  331. }
  332. set {
  333. image_key = value == null ? String.Empty : value;
  334. image_index = -1;
  335. if (owner != null)
  336. Layout ();
  337. Invalidate ();
  338. }
  339. }
  340. [Browsable (false)]
  341. public ImageList ImageList {
  342. get {
  343. if (owner == null)
  344. return null;
  345. else if (owner.View == View.LargeIcon)
  346. return owner.large_image_list;
  347. else
  348. return owner.small_image_list;
  349. }
  350. }
  351. [DefaultValue (0)]
  352. public int IndentCount {
  353. get {
  354. return indent_count;
  355. }
  356. set {
  357. if (value < 0)
  358. throw new ArgumentOutOfRangeException ("value");
  359. if (value == indent_count)
  360. return;
  361. indent_count = value;
  362. Invalidate ();
  363. }
  364. }
  365. [Browsable (false)]
  366. public int Index {
  367. get {
  368. if (owner == null)
  369. return -1;
  370. if (owner.VirtualMode)
  371. return display_index;
  372. if (display_index == -1)
  373. return owner.Items.IndexOf (this);
  374. return owner.GetItemIndex (display_index);
  375. }
  376. }
  377. [Browsable (false)]
  378. public ListView ListView {
  379. get { return owner; }
  380. }
  381. [Browsable (false)]
  382. [Localizable (true)]
  383. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  384. public string Name {
  385. get {
  386. return name;
  387. }
  388. set {
  389. name = value == null ? String.Empty : value;
  390. }
  391. }
  392. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  393. [Browsable (false)]
  394. public Point Position {
  395. get {
  396. if (owner != null && owner.VirtualMode)
  397. return owner.GetItemLocation (display_index);
  398. if (owner != null && !owner.IsHandleCreated)
  399. return new Point (-1, -1);
  400. return position;
  401. }
  402. set {
  403. if (owner == null || owner.View == View.Details || owner.View == View.List)
  404. return;
  405. if (owner.VirtualMode)
  406. throw new InvalidOperationException ();
  407. owner.ChangeItemLocation (display_index, value);
  408. }
  409. }
  410. // When ListView uses VirtualMode, selection state info
  411. // lives in the ListView, not in the item
  412. // Also, in VirtualMode we can't Reset() the selection
  413. [Browsable (false)]
  414. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  415. public bool Selected {
  416. get {
  417. if (owner != null && owner.VirtualMode)
  418. return owner.SelectedIndices.Contains (Index);
  419. return selected;
  420. }
  421. set {
  422. if (selected == value && owner != null && !owner.VirtualMode)
  423. return;
  424. SetSelectedCore (value);
  425. }
  426. }
  427. // Expose this method as internal so we can force an update in the selection.
  428. internal void SetSelectedCore (bool value)
  429. {
  430. if (owner != null) {
  431. if (value && !owner.MultiSelect)
  432. owner.SelectedIndices.Clear ();
  433. if (owner.VirtualMode) {
  434. if (value)
  435. owner.SelectedIndices.InsertIndex (Index);
  436. else
  437. owner.SelectedIndices.RemoveIndex (Index);
  438. } else {
  439. selected = value;
  440. owner.SelectedIndices.Reset (); // force re-population of list
  441. }
  442. owner.OnItemSelectionChanged (new ListViewItemSelectionChangedEventArgs (this, Index, value));
  443. owner.OnSelectedIndexChanged ();
  444. Invalidate ();
  445. } else
  446. selected = value;
  447. }
  448. [DefaultValue (-1)]
  449. [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
  450. typeof (System.Drawing.Design.UITypeEditor))]
  451. [Localizable (true)]
  452. [RefreshProperties (RefreshProperties.Repaint)]
  453. [RelatedImageListAttribute ("ListView.StateImageList")]
  454. [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
  455. public int StateImageIndex {
  456. get { return state_image_index; }
  457. set {
  458. if (value < -1 || value > 14)
  459. throw new ArgumentOutOfRangeException ("Invalid StateImageIndex. It must be in the range of [-1, 14].");
  460. state_image_index = value;
  461. }
  462. }
  463. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  464. [Editor ("System.Windows.Forms.Design.ListViewSubItemCollectionEditor, " + Consts.AssemblySystem_Design,
  465. typeof (System.Drawing.Design.UITypeEditor))]
  466. public ListViewSubItemCollection SubItems {
  467. get {
  468. if (sub_items.Count == 0)
  469. this.sub_items.Add (string.Empty);
  470. return sub_items;
  471. }
  472. }
  473. [Bindable (true)]
  474. [DefaultValue (null)]
  475. [Localizable (false)]
  476. [TypeConverter (typeof (StringConverter))]
  477. public object Tag {
  478. get { return tag; }
  479. set { tag = value; }
  480. }
  481. [Localizable (true)]
  482. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  483. public string Text {
  484. get {
  485. if (this.sub_items.Count > 0)
  486. return this.sub_items [0].Text;
  487. else
  488. return string.Empty;
  489. }
  490. set {
  491. if (SubItems [0].Text == value)
  492. return;
  493. sub_items [0].Text = value;
  494. if (owner != null)
  495. Layout ();
  496. Invalidate ();
  497. //UIA Framework: Generates Text changed
  498. OnUIATextChanged ();
  499. }
  500. }
  501. [DefaultValue (true)]
  502. public bool UseItemStyleForSubItems {
  503. get { return use_item_style; }
  504. set { use_item_style = value; }
  505. }
  506. [LocalizableAttribute(true)]
  507. [DefaultValue (null)]
  508. public ListViewGroup Group {
  509. get { return this.group; }
  510. set {
  511. if (group != value) {
  512. if (value == null)
  513. group.Items.Remove (this);
  514. else
  515. value.Items.Add (this);
  516. group = value;
  517. }
  518. }
  519. }
  520. [DefaultValue ("")]
  521. public string ToolTipText {
  522. get {
  523. return tooltip_text;
  524. }
  525. set {
  526. if (value == null)
  527. value = String.Empty;
  528. tooltip_text = value;
  529. }
  530. }
  531. #endregion // Public Instance Properties
  532. #region Public Instance Methods
  533. public void BeginEdit ()
  534. {
  535. if (owner != null && owner.LabelEdit) {
  536. owner.item_control.BeginEdit (this);
  537. }
  538. // FIXME: TODO
  539. // if (owner != null && owner.LabelEdit
  540. // && owner.Activation == ItemActivation.Standard)
  541. // allow editing
  542. // else
  543. // throw new InvalidOperationException ();
  544. }
  545. public virtual object Clone ()
  546. {
  547. ListViewItem clone = new ListViewItem ();
  548. clone.image_index = this.image_index;
  549. clone.is_checked = this.is_checked;
  550. clone.selected = this.selected;
  551. clone.font = this.font;
  552. clone.state_image_index = this.state_image_index;
  553. clone.sub_items = new ListViewSubItemCollection (this, null);
  554. foreach (ListViewSubItem subItem in this.sub_items)
  555. clone.sub_items.Add (subItem.Text, subItem.ForeColor,
  556. subItem.BackColor, subItem.Font);
  557. clone.tag = this.tag;
  558. clone.use_item_style = this.use_item_style;
  559. clone.owner = null;
  560. clone.name = name;
  561. clone.tooltip_text = tooltip_text;
  562. return clone;
  563. }
  564. public virtual void EnsureVisible ()
  565. {
  566. if (this.owner != null) {
  567. owner.EnsureVisible (owner.Items.IndexOf (this));
  568. }
  569. }
  570. public ListViewItem FindNearestItem (SearchDirectionHint searchDirection)
  571. {
  572. if (owner == null)
  573. return null;
  574. Point loc = owner.GetItemLocation (display_index);
  575. return owner.FindNearestItem (searchDirection, loc);
  576. }
  577. public Rectangle GetBounds (ItemBoundsPortion portion)
  578. {
  579. if (owner == null)
  580. return Rectangle.Empty;
  581. Rectangle rect;
  582. switch (portion) {
  583. case ItemBoundsPortion.Icon:
  584. rect = icon_rect;
  585. break;
  586. case ItemBoundsPortion.Label:
  587. rect = label_rect;
  588. break;
  589. case ItemBoundsPortion.ItemOnly:
  590. rect = item_rect;
  591. break;
  592. case ItemBoundsPortion.Entire:
  593. rect = bounds;
  594. break;
  595. default:
  596. throw new ArgumentException ("Invalid value for portion.");
  597. }
  598. Point item_loc = owner.GetItemLocation (DisplayIndex);
  599. rect.X += item_loc.X;
  600. rect.Y += item_loc.Y;
  601. return rect;
  602. }
  603. void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
  604. {
  605. Serialize (info, context);
  606. }
  607. public ListViewSubItem GetSubItemAt (int x, int y)
  608. {
  609. if (owner != null && owner.View != View.Details)
  610. return null;
  611. foreach (ListViewSubItem sub_item in sub_items)
  612. if (sub_item.Bounds.Contains (x, y))
  613. return sub_item;
  614. return null;
  615. }
  616. public virtual void Remove ()
  617. {
  618. if (owner == null)
  619. return;
  620. owner.item_control.CancelEdit (this);
  621. owner.Items.Remove (this);
  622. owner = null;
  623. }
  624. public override string ToString ()
  625. {
  626. return string.Format ("ListViewItem: {0}", this.Text);
  627. }
  628. #endregion // Public Instance Methods
  629. #region Protected Methods
  630. protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
  631. {
  632. sub_items = new ListViewSubItemCollection (this, null);
  633. int sub_items_count = 0;
  634. foreach (SerializationEntry entry in info) {
  635. switch (entry.Name) {
  636. case "Text":
  637. sub_items.Add ((string)entry.Value);
  638. break;
  639. case "Font":
  640. font = (Font)entry.Value;
  641. break;
  642. case "Checked":
  643. is_checked = (bool)entry.Value;
  644. break;
  645. case "ImageIndex":
  646. image_index = (int)entry.Value;
  647. break;
  648. case "StateImageIndex":
  649. state_image_index = (int)entry.Value;
  650. break;
  651. case "UseItemStyleForSubItems":
  652. use_item_style = (bool)entry.Value;
  653. break;
  654. case "SubItemCount":
  655. sub_items_count = (int)entry.Value;
  656. break;
  657. case "Group":
  658. group = (ListViewGroup)entry.Value;
  659. break;
  660. case "ImageKey":
  661. if (image_index == -1)
  662. image_key = (string)entry.Value;
  663. break;
  664. }
  665. }
  666. Type subitem_type = typeof (ListViewSubItem);
  667. if (sub_items_count > 0) {
  668. sub_items.Clear (); // .net fixup
  669. Text = info.GetString ("Text");
  670. for (int i = 0; i < sub_items_count - 1; i++)
  671. sub_items.Add ((ListViewSubItem)info.GetValue ("SubItem" + (i + 1), subitem_type));
  672. }
  673. // After any sub item has been added.
  674. ForeColor = (Color)info.GetValue ("ForeColor", typeof (Color));
  675. BackColor = (Color)info.GetValue ("BackColor", typeof (Color));
  676. }
  677. protected virtual void Serialize (SerializationInfo info, StreamingContext context)
  678. {
  679. info.AddValue ("Text", Text);
  680. info.AddValue ("Font", Font);
  681. info.AddValue ("ImageIndex", image_index);
  682. info.AddValue ("Checked", is_checked);
  683. info.AddValue ("StateImageIndex", state_image_index);
  684. info.AddValue ("UseItemStyleForSubItems", use_item_style);
  685. info.AddValue ("BackColor", BackColor);
  686. info.AddValue ("ForeColor", ForeColor);
  687. info.AddValue ("ImageKey", image_key);
  688. if (group != null)
  689. info.AddValue ("Group", group);
  690. if (sub_items.Count > 1) {
  691. info.AddValue ("SubItemCount", sub_items.Count);
  692. for (int i = 1; i < sub_items.Count; i++) {
  693. info.AddValue ("SubItem" + i, sub_items [i]);
  694. }
  695. }
  696. }
  697. #endregion // Protected Methods
  698. #region Private Internal Methods
  699. internal Rectangle CheckRectReal {
  700. get {
  701. Rectangle rect = checkbox_rect;
  702. Point item_loc = owner.GetItemLocation (DisplayIndex);
  703. rect.X += item_loc.X;
  704. rect.Y += item_loc.Y;
  705. return rect;
  706. }
  707. }
  708. Rectangle text_bounds;
  709. internal Rectangle TextBounds {
  710. get {
  711. // Call Layout() if it hasn't been called before.
  712. if (owner.VirtualMode && bounds == new Rectangle (-1, -1, -1, -1))
  713. Layout ();
  714. Rectangle result = text_bounds;
  715. Point loc = owner.GetItemLocation (DisplayIndex);
  716. result.X += loc.X;
  717. result.Y += loc.Y;
  718. return result;
  719. }
  720. }
  721. internal int DisplayIndex {
  722. get {
  723. // Special case for Details view
  724. // and no columns (which means no Layout at all)
  725. if (display_index == -1)
  726. return owner.Items.IndexOf (this);
  727. return display_index;
  728. }
  729. set {
  730. display_index = value;
  731. }
  732. }
  733. internal bool Hot {
  734. get {
  735. return Index == owner.HotItemIndex;
  736. }
  737. }
  738. internal Font HotFont {
  739. get {
  740. if (hot_font == null)
  741. hot_font = new Font (Font, Font.Style | FontStyle.Underline);
  742. return hot_font;
  743. }
  744. }
  745. internal ListView Owner {
  746. set {
  747. if (owner == value)
  748. return;
  749. owner = value;
  750. }
  751. }
  752. internal void SetGroup (ListViewGroup group)
  753. {
  754. this.group = group;
  755. }
  756. internal void SetPosition (Point position)
  757. {
  758. this.position = position;
  759. }
  760. // When focus changed, we need to invalidate area
  761. // with previous layout and with the new one
  762. void UpdateFocusedState ()
  763. {
  764. if (owner != null) {
  765. Invalidate ();
  766. Layout ();
  767. Invalidate ();
  768. }
  769. }
  770. internal void Invalidate ()
  771. {
  772. if (owner == null || owner.item_control == null || owner.updating)
  773. return;
  774. // Add some padding to bounds (focused extra space, selection)
  775. Rectangle rect = Bounds;
  776. rect.Inflate (1, 1);
  777. owner.item_control.Invalidate (rect);
  778. }
  779. internal void Layout ()
  780. {
  781. if (owner == null)
  782. return;
  783. int item_ht;
  784. Rectangle total;
  785. Size text_size = owner.text_size;
  786. checkbox_rect = Rectangle.Empty;
  787. if (owner.CheckBoxes)
  788. checkbox_rect.Size = owner.CheckBoxSize;
  789. switch (owner.View) {
  790. case View.Details:
  791. // LAMESPEC: MSDN says, "In all views except the details
  792. // view of the ListView, this value specifies the same
  793. // bounding rectangle as the Entire value." Actually, it
  794. // returns same bounding rectangles for Item and Entire
  795. // values in the case of Details view.
  796. int x_offset = 0;
  797. if (owner.SmallImageList != null)
  798. x_offset = indent_count * owner.SmallImageList.ImageSize.Width;
  799. // Handle reordered column
  800. if (owner.Columns.Count > 0)
  801. checkbox_rect.X = owner.Columns[0].Rect.X + x_offset;
  802. icon_rect = label_rect = Rectangle.Empty;
  803. icon_rect.X = checkbox_rect.Right + 2;
  804. item_ht = owner.ItemSize.Height;
  805. if (owner.SmallImageList != null)
  806. icon_rect.Width = owner.SmallImageList.ImageSize.Width;
  807. label_rect.Height = icon_rect.Height = item_ht;
  808. checkbox_rect.Y = item_ht - checkbox_rect.Height;
  809. label_rect.X = icon_rect.Width > 0 ? icon_rect.Right + 1 : icon_rect.Right;
  810. if (owner.Columns.Count > 0)
  811. label_rect.Width = owner.Columns[0].Wd - label_rect.X + checkbox_rect.X;
  812. else
  813. label_rect.Width = text_size.Width;
  814. SizeF text_sz = TextRenderer.MeasureString (Text, Font);
  815. text_bounds = label_rect;
  816. text_bounds.Width = (int) text_sz.Width;
  817. item_rect = total = Rectangle.Union
  818. (Rectangle.Union (checkbox_rect, icon_rect), label_rect);
  819. bounds.Size = total.Size;
  820. item_rect.Width = 0;
  821. bounds.Width = 0;
  822. for (int i = 0; i < owner.Columns.Count; i++) {
  823. item_rect.Width += owner.Columns [i].Wd;
  824. bounds.Width += owner.Columns [i].Wd;
  825. }
  826. // Bounds for sub items
  827. int n = Math.Min (owner.Columns.Count, sub_items.Count);
  828. for (int i = 0; i < n; i++) {
  829. Rectangle col_rect = owner.Columns [i].Rect;
  830. sub_items [i].SetBounds (col_rect.X, 0, col_rect.Width, item_ht);
  831. }
  832. break;
  833. case View.LargeIcon:
  834. label_rect = icon_rect = Rectangle.Empty;
  835. SizeF sz = TextRenderer.MeasureString (Text, Font);
  836. if ((int) sz.Width > text_size.Width) {
  837. if (Focused && owner.InternalContainsFocus) {
  838. int text_width = text_size.Width;
  839. StringFormat format = new StringFormat ();
  840. format.Alignment = StringAlignment.Center;
  841. sz = TextRenderer.MeasureString (Text, Font, text_width, format);
  842. text_size.Height = (int) sz.Height;
  843. } else
  844. text_size.Height = 2 * (int) sz.Height;
  845. }
  846. if (owner.LargeImageList != null) {
  847. icon_rect.Width = owner.LargeImageList.ImageSize.Width;
  848. icon_rect.Height = owner.LargeImageList.ImageSize.Height;
  849. }
  850. if (checkbox_rect.Height > icon_rect.Height)
  851. icon_rect.Y = checkbox_rect.Height - icon_rect.Height;
  852. else
  853. checkbox_rect.Y = icon_rect.Height - checkbox_rect.Height;
  854. if (text_size.Width <= icon_rect.Width) {
  855. icon_rect.X = checkbox_rect.Width + 1;
  856. label_rect.X = icon_rect.X + (icon_rect.Width - text_size.Width) / 2;
  857. label_rect.Y = icon_rect.Bottom + 2;
  858. label_rect.Size = text_size;
  859. } else {
  860. int centerX = text_size.Width / 2;
  861. icon_rect.X = checkbox_rect.Width + 1 + centerX - icon_rect.Width / 2;
  862. label_rect.X = checkbox_rect.Width + 1;
  863. label_rect.Y = icon_rect.Bottom + 2;
  864. label_rect.Size = text_size;
  865. }
  866. item_rect = Rectangle.Union (icon_rect, label_rect);
  867. total = Rectangle.Union (item_rect, checkbox_rect);
  868. bounds.Size = total.Size;
  869. break;
  870. case View.List:
  871. case View.SmallIcon:
  872. label_rect = icon_rect = Rectangle.Empty;
  873. icon_rect.X = checkbox_rect.Width + 1;
  874. item_ht = Math.Max (owner.CheckBoxSize.Height, text_size.Height);
  875. if (owner.SmallImageList != null) {
  876. item_ht = Math.Max (item_ht, owner.SmallImageList.ImageSize.Height);
  877. icon_rect.Width = owner.SmallImageList.ImageSize.Width;
  878. icon_rect.Height = owner.SmallImageList.ImageSize.Height;
  879. }
  880. checkbox_rect.Y = item_ht - checkbox_rect.Height;
  881. label_rect.X = icon_rect.Right + 1;
  882. label_rect.Width = text_size.Width;
  883. label_rect.Height = icon_rect.Height = item_ht;
  884. item_rect = Rectangle.Union (icon_rect, label_rect);
  885. total = Rectangle.Union (item_rect, checkbox_rect);
  886. bounds.Size = total.Size;
  887. break;
  888. case View.Tile:
  889. if (!Application.VisualStylesEnabled)
  890. goto case View.LargeIcon;
  891. label_rect = icon_rect = Rectangle.Empty;
  892. if (owner.LargeImageList != null) {
  893. icon_rect.Width = owner.LargeImageList.ImageSize.Width;
  894. icon_rect.Height = owner.LargeImageList.ImageSize.Height;
  895. }
  896. int separation = 2;
  897. SizeF tsize = TextRenderer.MeasureString (Text, Font);
  898. int main_item_height = (int) Math.Ceiling (tsize.Height);
  899. int main_item_width = (int) Math.Ceiling (tsize.Width);
  900. sub_items [0].bounds.Height = main_item_height;
  901. // Set initial values for subitem's layout
  902. int total_height = main_item_height;
  903. int max_subitem_width = main_item_width;
  904. int count = Math.Min (owner.Columns.Count, sub_items.Count);
  905. for (int i = 1; i < count; i++) { // Ignore first column and first subitem
  906. ListViewSubItem sub_item = sub_items [i];
  907. if (sub_item.Text == null || sub_item.Text.Length == 0)
  908. continue;
  909. tsize = TextRenderer.MeasureString (sub_item.Text, sub_item.Font);
  910. int width = (int)Math.Ceiling (tsize.Width);
  911. if (width > max_subitem_width)
  912. max_subitem_width = width;
  913. int height = (int)Math.Ceiling (tsize.Height);
  914. total_height += height + separation;
  915. sub_item.bounds.Height = height;
  916. }
  917. max_subitem_width = Math.Min (max_subitem_width, owner.TileSize.Width - (icon_rect.Width + 4));
  918. label_rect.X = icon_rect.Right + 4;
  919. label_rect.Y = owner.TileSize.Height / 2 - total_height / 2;
  920. label_rect.Width = max_subitem_width;
  921. label_rect.Height = total_height;
  922. // Main item - always set bounds for it
  923. sub_items [0].SetBounds (label_rect.X, label_rect.Y, max_subitem_width, sub_items [0].bounds.Height);
  924. // Second pass to assign bounds for every sub item
  925. int current_y = sub_items [0].bounds.Bottom + separation;
  926. for (int j = 1; j < count; j++) {
  927. ListViewSubItem sub_item = sub_items [j];
  928. if (sub_item.Text == null || sub_item.Text.Length == 0)
  929. continue;
  930. sub_item.SetBounds (label_rect.X, current_y, max_subitem_width, sub_item.bounds.Height);
  931. current_y += sub_item.Bounds.Height + separation;
  932. }
  933. item_rect = Rectangle.Union (icon_rect, label_rect);
  934. bounds.Size = item_rect.Size;
  935. break;
  936. }
  937. }
  938. #endregion // Private Internal Methods
  939. #region Subclasses
  940. [DefaultProperty ("Text")]
  941. [DesignTimeVisible (false)]
  942. [Serializable]
  943. [ToolboxItem (false)]
  944. [TypeConverter (typeof(ListViewSubItemConverter))]
  945. public class ListViewSubItem
  946. {
  947. [NonSerialized]
  948. internal ListViewItem owner;
  949. private string text = string.Empty;
  950. private string name;
  951. private object userData;
  952. private SubItemStyle style;
  953. [NonSerialized]
  954. internal Rectangle bounds;
  955. #region UIA Framework: Methods, Properties and Events
  956. [field:NonSerialized]
  957. internal event EventHandler UIATextChanged;
  958. private void OnUIATextChanged ()
  959. {
  960. if (UIATextChanged != null)
  961. UIATextChanged (this, EventArgs.Empty);
  962. }
  963. #endregion // UIA Framework: Methods, Properties and Events
  964. #region Public Constructors
  965. public ListViewSubItem ()
  966. : this (null, string.Empty, Color.Empty,
  967. Color.Empty, null)
  968. {
  969. }
  970. public ListViewSubItem (ListViewItem owner, string text)
  971. : this (owner, text, Color.Empty,
  972. Color.Empty, null)
  973. {
  974. }
  975. public ListViewSubItem (ListViewItem owner, string text, Color foreColor,
  976. Color backColor, Font font)
  977. {
  978. this.owner = owner;
  979. Text = text;
  980. this.style = new SubItemStyle (foreColor,
  981. backColor, font);
  982. }
  983. #endregion // Public Constructors
  984. #region Public Instance Properties
  985. public Color BackColor {
  986. get {
  987. if (style.backColor != Color.Empty)
  988. return style.backColor;
  989. if (this.owner != null && this.owner.ListView != null)
  990. return this.owner.ListView.BackColor;
  991. return ThemeEngine.Current.ColorWindow;
  992. }
  993. set {
  994. style.backColor = value;
  995. Invalidate ();
  996. }
  997. }
  998. [Browsable (false)]
  999. public Rectangle Bounds {
  1000. get {
  1001. Rectangle retval = bounds;
  1002. if (owner != null) {
  1003. retval.X += owner.Bounds.X;
  1004. retval.Y += owner.Bounds.Y;
  1005. }
  1006. return retval;
  1007. }
  1008. }
  1009. [Localizable (true)]
  1010. public Font Font {
  1011. get {
  1012. if (style.font != null)
  1013. return style.font;
  1014. else if (owner != null)
  1015. return owner.Font;
  1016. return ThemeEngine.Current.DefaultFont;
  1017. }
  1018. set {
  1019. if (style.font == value)
  1020. return;
  1021. style.font = value;
  1022. Invalidate ();
  1023. }
  1024. }
  1025. public Color ForeColor {
  1026. get {
  1027. if (style.foreColor != Color.Empty)
  1028. return style.foreColor;
  1029. if (this.owner != null && this.owner.ListView != null)
  1030. return this.owner.ListView.ForeColor;
  1031. return ThemeEngine.Current.ColorWindowText;
  1032. }
  1033. set {
  1034. style.foreColor = value;
  1035. Invalidate ();
  1036. }
  1037. }
  1038. [Localizable (true)]
  1039. public string Name {
  1040. get {
  1041. if (name == null)
  1042. return string.Empty;
  1043. return name;
  1044. }
  1045. set {
  1046. name = value;
  1047. }
  1048. }
  1049. [TypeConverter (typeof (StringConverter))]
  1050. [BindableAttribute (true)]
  1051. [DefaultValue (null)]
  1052. [Localizable (false)]
  1053. public object Tag {
  1054. get {
  1055. return userData;
  1056. }
  1057. set {
  1058. userData = value;
  1059. }
  1060. }
  1061. [Localizable (true)]
  1062. public string Text {
  1063. get { return text; }
  1064. set {
  1065. if(text == value)
  1066. return;
  1067. if(value == null)
  1068. text = string.Empty;
  1069. else
  1070. text = value;
  1071. Invalidate ();
  1072. // UIA Framework: Generates SubItem TextChanged
  1073. OnUIATextChanged ();
  1074. }
  1075. }
  1076. #endregion // Public Instance Properties
  1077. #region Public Methods
  1078. public void ResetStyle ()
  1079. {
  1080. style.Reset ();
  1081. Invalidate ();
  1082. }
  1083. public override string ToString ()
  1084. {
  1085. return string.Format ("ListViewSubItem {{0}}", text);
  1086. }
  1087. #endregion // Public Methods
  1088. #region Private Methods
  1089. private void Invalidate ()
  1090. {
  1091. if (owner == null || owner.owner == null)
  1092. return;
  1093. owner.Invalidate ();
  1094. }
  1095. [OnDeserialized]
  1096. void OnDeserialized (StreamingContext context)
  1097. {
  1098. name = null;
  1099. userData = null;
  1100. }
  1101. internal int Height {
  1102. get {
  1103. return bounds.Height;
  1104. }
  1105. }
  1106. internal void SetBounds (int x, int y, int width, int height)
  1107. {
  1108. bounds = new Rectangle (x, y, width, height);
  1109. }
  1110. #endregion // Private Methods
  1111. [Serializable]
  1112. class SubItemStyle
  1113. {
  1114. public SubItemStyle ()
  1115. {
  1116. }
  1117. public SubItemStyle (Color foreColor, Color backColor, Font font)
  1118. {
  1119. this.foreColor = foreColor;
  1120. this.backColor = backColor;
  1121. this.font = font;
  1122. }
  1123. public void Reset ()
  1124. {
  1125. foreColor = Color.Empty;
  1126. backColor = Color.Empty;
  1127. font = null;
  1128. }
  1129. public Color backColor;
  1130. public Color foreColor;
  1131. public Font font;
  1132. }
  1133. }
  1134. public class ListViewSubItemCollection : IList, ICollection, IEnumerable
  1135. {
  1136. private ArrayList list;
  1137. internal ListViewItem owner;
  1138. #region Public Constructors
  1139. public ListViewSubItemCollection (ListViewItem owner) : this (owner, owner.Text)
  1140. {
  1141. }
  1142. #endregion // Public Constructors
  1143. internal ListViewSubItemCollection (ListViewItem owner, string text)
  1144. {
  1145. this.owner = owner;
  1146. this.list = new ArrayList ();
  1147. if (text != null)
  1148. Add (text);
  1149. }
  1150. #region Public Properties
  1151. [Browsable (false)]
  1152. public int Count {
  1153. get { return list.Count; }
  1154. }
  1155. public bool IsReadOnly {
  1156. get { return false; }
  1157. }
  1158. public ListViewSubItem this [int index] {
  1159. get { return (ListViewSubItem) list [index]; }
  1160. set {
  1161. value.owner = owner;
  1162. list [index] = value;
  1163. owner.Layout ();
  1164. owner.Invalidate ();
  1165. }
  1166. }
  1167. public virtual ListViewSubItem this [string key] {
  1168. get {
  1169. int idx = IndexOfKey (key);
  1170. if (idx == -1)
  1171. return null;
  1172. return (ListViewSubItem) list [idx];
  1173. }
  1174. }
  1175. bool ICollection.IsSynchronized {
  1176. get { return list.IsSynchronized; }
  1177. }
  1178. object ICollection.SyncRoot {
  1179. get { return list.SyncRoot; }
  1180. }
  1181. bool IList.IsFixedSize {
  1182. get { return list.IsFixedSize; }
  1183. }
  1184. object IList.this [int index] {
  1185. get { return this [index]; }
  1186. set {
  1187. if (! (value is ListViewSubItem))
  1188. throw new ArgumentException ("Not of type ListViewSubItem", "value");
  1189. this [index] = (ListViewSubItem) value;
  1190. }
  1191. }
  1192. #endregion // Public Properties
  1193. #region Public Methods
  1194. public ListViewSubItem Add (ListViewSubItem item)
  1195. {
  1196. AddSubItem (item);
  1197. owner.Layout ();
  1198. owner.Invalidate ();
  1199. return item;
  1200. }
  1201. public ListViewSubItem Add (string text)
  1202. {
  1203. ListViewSubItem item = new ListViewSubItem (owner, text);
  1204. return Add (item);
  1205. }
  1206. public ListViewSubItem Add (string text, Color foreColor,
  1207. Color backColor, Font font)
  1208. {
  1209. ListViewSubItem item = new ListViewSubItem (owner, text,
  1210. foreColor, backColor, font);
  1211. return Add (item);
  1212. }
  1213. public void AddRange (ListViewSubItem [] items)
  1214. {
  1215. if (items == null)
  1216. throw new ArgumentNullException ("items");
  1217. foreach (ListViewSubItem item in items) {
  1218. if (item == null)
  1219. continue;
  1220. AddSubItem (item);
  1221. }
  1222. owner.Layout ();
  1223. owner.Invalidate ();
  1224. }
  1225. public void AddRange (string [] items)
  1226. {
  1227. if (items == null)
  1228. throw new ArgumentNullException ("items");
  1229. foreach (string item in items) {
  1230. if (item == null)
  1231. continue;
  1232. AddSubItem (new ListViewSubItem (owner, item));
  1233. }
  1234. owner.Layout ();
  1235. owner.Invalidate ();
  1236. }
  1237. public void AddRange (string [] items, Color foreColor,
  1238. Color backColor, Font font)
  1239. {
  1240. if (items == null)
  1241. throw new ArgumentNullException ("items");
  1242. foreach (string item in items) {
  1243. if (item == null)
  1244. continue;
  1245. AddSubItem (new ListViewSubItem (owner, item, foreColor, backColor, font));
  1246. }
  1247. owner.Layout ();
  1248. owner.Invalidate ();
  1249. }
  1250. void AddSubItem (ListViewSubItem subItem)
  1251. {
  1252. subItem.owner = owner;
  1253. list.Add (subItem);
  1254. //UIA Framework
  1255. subItem.UIATextChanged += OnUIASubItemTextChanged;
  1256. }
  1257. public void Clear ()
  1258. {
  1259. list.Clear ();
  1260. }
  1261. public bool Contains (ListViewSubItem subItem)
  1262. {
  1263. return list.Contains (subItem);
  1264. }
  1265. public virtual bool ContainsKey (string key)
  1266. {
  1267. return IndexOfKey (key) != -1;
  1268. }
  1269. public IEnumerator GetEnumerator ()
  1270. {
  1271. return list.GetEnumerator ();
  1272. }
  1273. void ICollection.CopyTo (Array dest, int index)
  1274. {
  1275. list.CopyTo (dest, index);
  1276. }
  1277. int IList.Add (object item)
  1278. {
  1279. if (! (item is ListViewSubItem)) {
  1280. throw new ArgumentException ("Not of type ListViewSubItem", "item");
  1281. }
  1282. ListViewSubItem sub_item = (ListViewSubItem) item;
  1283. sub_item.owner = this.owner;
  1284. //UIA Framework
  1285. sub_item.UIATextChanged += OnUIASubItemTextChanged;
  1286. return list.Add (sub_item);
  1287. }
  1288. bool IList.Contains (object subItem)
  1289. {
  1290. if (! (subItem is ListViewSubItem)) {
  1291. throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
  1292. }
  1293. return this.Contains ((ListViewSubItem) subItem);
  1294. }
  1295. int IList.IndexOf (object subItem)
  1296. {
  1297. if (! (subItem is ListViewSubItem)) {
  1298. throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
  1299. }
  1300. return this.IndexOf ((ListViewSubItem) subItem);
  1301. }
  1302. void IList.Insert (int index, object item)
  1303. {
  1304. if (! (item is ListViewSubItem)) {
  1305. throw new ArgumentException ("Not of type ListViewSubItem", "item");
  1306. }
  1307. this.Insert (index, (ListViewSubItem) item);
  1308. }
  1309. void IList.Remove (object item)
  1310. {
  1311. if (! (item is ListViewSubItem)) {
  1312. throw new ArgumentException ("Not of type ListViewSubItem", "item");
  1313. }
  1314. this.Remove ((ListViewSubItem) item);
  1315. }
  1316. public int IndexOf (ListViewSubItem subItem)
  1317. {
  1318. return list.IndexOf (subItem);
  1319. }
  1320. public virtual int IndexOfKey (string key)
  1321. {
  1322. if (key == null || key.Length == 0)
  1323. return -1;
  1324. for (int i = 0; i < list.Count; i++) {
  1325. ListViewSubItem l = (ListViewSubItem) list [i];
  1326. if (String.Compare (l.Name, key, true) == 0)
  1327. return i;
  1328. }
  1329. return -1;
  1330. }
  1331. public void Insert (int index, ListViewSubItem item)
  1332. {
  1333. item.owner = this.owner;
  1334. list.Insert (index, item);
  1335. owner.Layout ();
  1336. owner.Invalidate ();
  1337. //UIA Framework
  1338. item.UIATextChanged += OnUIASubItemTextChanged;
  1339. }
  1340. public void Remove (ListViewSubItem item)
  1341. {
  1342. list.Remove (item);
  1343. owner.Layout ();
  1344. owner.Invalidate ();
  1345. //UIA Framework
  1346. item.UIATextChanged -= OnUIASubItemTextChanged;
  1347. }
  1348. public virtual void RemoveByKey (string key)
  1349. {
  1350. int idx = IndexOfKey (key);
  1351. if (idx != -1)
  1352. RemoveAt (idx);
  1353. }
  1354. public void RemoveAt (int index)
  1355. {
  1356. //UIA Framework
  1357. if (index >= 0 && index < list.Count)
  1358. ((ListViewSubItem) list [index]).UIATextChanged -= OnUIASubItemTextChanged;
  1359. list.RemoveAt (index);
  1360. }
  1361. #endregion // Public Methods
  1362. #region UIA Event Handler
  1363. private void OnUIASubItemTextChanged (object sender, EventArgs args)
  1364. {
  1365. owner.OnUIASubItemTextChanged (new LabelEditEventArgs (list.IndexOf (sender)));
  1366. }
  1367. #endregion
  1368. }
  1369. #endregion // Subclasses
  1370. }
  1371. }