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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004 Novell, Inc. (http://www.novell.com)
23 // Ravindra (rkumar@novell.com)
26 // - Drawing of focus rectangle
33 using System.Collections;
34 using System.ComponentModel;
36 using System.Runtime.Serialization;
38 namespace System.Windows.Forms
40 [DefaultProperty ("Text")]
41 [DesignTimeVisible (false)]
44 [TypeConverter (typeof (ListViewItemConverter))]
45 public class ListViewItem : ICloneable, ISerializable
47 #region Instance Variables
48 private int image_index = -1;
49 private bool is_checked = false;
50 private bool is_focused = false;
51 private int state_image_index = -1;
52 private ListViewSubItemCollection sub_items;
54 private bool use_item_style = true;
57 Rectangle checkbox_rect; // calculated by CalcListViewItem method
64 #endregion Instance Variables
66 #region Public Constructors
67 public ListViewItem ()
69 this.sub_items = new ListViewSubItemCollection (this);
70 this.sub_items.Add ("");
73 public ListViewItem (string text) : this (text, -1)
77 public ListViewItem (string [] items) : this (items, -1)
81 public ListViewItem (ListViewItem.ListViewSubItem [] subItems, int imageIndex)
83 this.sub_items = new ListViewSubItemCollection (this);
84 this.sub_items.AddRange (subItems);
85 this.image_index = imageIndex;
88 public ListViewItem (string text, int imageIndex)
90 this.image_index = imageIndex;
91 this.sub_items = new ListViewSubItemCollection (this);
92 this.sub_items.Add (text);
95 public ListViewItem (string [] items, int imageIndex)
97 this.sub_items = new ListViewSubItemCollection (this);
98 this.sub_items.AddRange (items);
99 this.image_index = imageIndex;
102 public ListViewItem (string [] items, int imageIndex, Color foreColor,
103 Color backColor, Font font)
105 this.sub_items = new ListViewSubItemCollection (this);
106 this.sub_items.AddRange (items);
107 this.image_index = imageIndex;
108 ForeColor = foreColor;
109 BackColor = backColor;
112 #endregion // Public Constructors
114 #region Public Instance Properties
115 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
116 public Color BackColor {
118 if (sub_items.Count > 0)
119 return sub_items[0].BackColor;
122 return owner.BackColor;
124 return ThemeEngine.Current.ColorWindow;
127 set { sub_items[0].BackColor = value; }
131 public Rectangle Bounds {
133 return GetBounds (ItemBoundsPortion.Entire);
137 [DefaultValue (false)]
138 [RefreshProperties (RefreshProperties.Repaint)]
139 public bool Checked {
140 get { return is_checked; }
142 if (is_checked == value)
149 if (owner.CheckedItems.Contains (this) == false) {
150 owner.CheckedItems.list.Add (this);
151 owner.CheckedIndices.list.Add (this.Index);
155 owner.CheckedItems.list.Remove (this);
156 owner.CheckedIndices.list.Remove (this.Index);
166 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
167 public bool Focused {
168 get { return is_focused; }
170 if (is_focused == value)
182 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
185 if (sub_items.Count > 0)
186 return sub_items[0].Font;
191 return ThemeEngine.Current.DefaultFont;
194 if (sub_items[0].Font == value)
197 sub_items[0].Font = value;
205 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
206 public Color ForeColor {
208 if (sub_items.Count > 0)
209 return sub_items[0].ForeColor;
212 return owner.ForeColor;
214 return ThemeEngine.Current.ColorWindowText;
216 set { sub_items[0].ForeColor = value; }
220 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
221 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
222 typeof (System.Drawing.Design.UITypeEditor))]
224 [TypeConverter (typeof (ImageIndexConverter))]
225 public int ImageIndex {
226 get { return image_index; }
229 throw new ArgumentException ("Invalid ImageIndex. It must be greater than or equal to -1.");
240 public ImageList ImageList {
244 else if (owner.View == View.LargeIcon)
245 return owner.large_image_list;
247 return owner.small_image_list;
257 return owner.Items.IndexOf (this);
262 public ListView ListView {
263 get { return owner; }
267 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
268 public bool Selected {
269 get { return selected; }
271 if (selected == value)
283 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
284 typeof (System.Drawing.Design.UITypeEditor))]
286 [TypeConverter (typeof (ImageIndexConverter))]
287 public int StateImageIndex {
288 get { return state_image_index; }
290 if (value < -1 || value > 14)
291 throw new ArgumentOutOfRangeException ("Invalid StateImageIndex. It must be in the range of [-1, 14].");
293 state_image_index = value;
297 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
298 public ListViewSubItemCollection SubItems {
299 get { return sub_items; }
303 [DefaultValue (null)]
304 [Localizable (false)]
305 [TypeConverter (typeof (StringConverter))]
312 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
315 if (this.sub_items.Count > 0)
316 return this.sub_items [0].Text;
321 if (sub_items [0].Text == value)
324 sub_items [0].Text = value;
332 [DefaultValue (true)]
333 public bool UseItemStyleForSubItems {
334 get { return use_item_style; }
335 set { use_item_style = value; }
337 #endregion // Public Instance Properties
339 #region Public Instance Methods
340 public void BeginEdit ()
343 // if (owner != null && owner.LabelEdit
344 // && owner.Activation == ItemActivation.Standard)
347 // throw new InvalidOperationException ();
350 public virtual object Clone ()
352 ListViewItem clone = new ListViewItem ();
353 clone.image_index = this.image_index;
354 clone.is_checked = this.is_checked;
355 clone.is_focused = this.is_focused;
356 clone.selected = this.selected;
357 clone.state_image_index = this.state_image_index;
358 clone.sub_items = new ListViewSubItemCollection (this);
360 foreach (ListViewSubItem subItem in this.sub_items)
361 clone.sub_items.Add (subItem.Text, subItem.ForeColor,
362 subItem.BackColor, subItem.Font);
363 clone.tag = this.tag;
364 clone.use_item_style = this.use_item_style;
370 public virtual void EnsureVisible ()
372 if (this.owner != null) {
373 owner.EnsureVisible (owner.Items.IndexOf (this));
377 public Rectangle GetBounds (ItemBoundsPortion portion)
380 return Rectangle.Empty;
385 case ItemBoundsPortion.Icon:
389 case ItemBoundsPortion.Label:
393 case ItemBoundsPortion.ItemOnly:
397 case ItemBoundsPortion.Entire:
399 rect.X -= owner.h_marker;
400 rect.Y -= owner.v_marker;
404 throw new ArgumentException ("Invalid value for portion.");
407 rect.X += bounds.X - owner.h_marker;
408 rect.Y += bounds.Y - owner.v_marker;
412 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
417 public virtual void Remove ()
420 owner.Items.Remove (this);
424 public override string ToString ()
426 return string.Format ("ListViewItem: {0}", this.Text);
428 #endregion // Public Instance Methods
430 #region Protected Methods
431 protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
436 protected virtual void Serialize (SerializationInfo info, StreamingContext context)
440 #endregion // Protected Methods
442 #region Private Internal Methods
443 internal Rectangle CheckRectReal {
445 Rectangle rect = checkbox_rect;
446 rect.X += bounds.X - owner.h_marker;
447 rect.Y += bounds.Y - owner.v_marker;
452 Rectangle CheckRect {
453 get { return this.checkbox_rect; }
457 get { return this.icon_rect; }
460 Rectangle LabelRect {
461 get { return this.label_rect; }
464 internal Point Location {
466 if (bounds.X == value.X && bounds.Y == value.Y)
469 Rectangle prev = Bounds;
473 if (prev != Rectangle.Empty)
474 owner.Invalidate (prev);
475 owner.Invalidate (Bounds);
480 internal ListView Owner {
492 private void Invalidate ()
497 owner.Invalidate (Bounds);
500 internal void Layout ()
504 Size text_size = owner.text_size;
506 checkbox_rect = Rectangle.Empty;
507 if (owner.CheckBoxes)
508 checkbox_rect.Size = owner.CheckBoxSize;
510 switch (owner.View) {
512 // LAMESPEC: MSDN says, "In all views except the details
513 // view of the ListView, this value specifies the same
514 // bounding rectangle as the Entire value." Actually, it
515 // returns same bounding rectangles for Item and Entire
516 // values in the case of Details view.
518 icon_rect = label_rect = Rectangle.Empty;
519 icon_rect.X = checkbox_rect.Width + 2;
520 item_ht = Math.Max (owner.CheckBoxSize.Height, text_size.Height);
522 if (owner.SmallImageList != null) {
523 item_ht = Math.Max (item_ht, owner.SmallImageList.ImageSize.Height);
524 icon_rect.Width = owner.SmallImageList.ImageSize.Width;
527 label_rect.Height = icon_rect.Height = item_ht;
528 checkbox_rect.Y = icon_rect.Height - checkbox_rect.Height - 1;
530 label_rect.X = icon_rect.Right + 1;
532 if (owner.Columns.Count > 0)
533 label_rect.Width = Math.Max (text_size.Width, owner.Columns[0].Wd);
535 label_rect.Width = text_size.Width;
537 item_rect = total = Rectangle.Union
538 (Rectangle.Union (checkbox_rect, icon_rect), label_rect);
539 bounds.Size = total.Size;
541 // Take into account the rest of columns. First column
542 // is already taken into account above.
543 for (int i = 1; i < owner.Columns.Count; i++) {
544 item_rect.Width += owner.Columns [i].Wd;
545 bounds.Width += owner.Columns [i].Wd;
550 label_rect = icon_rect = Rectangle.Empty;
552 if (owner.LargeImageList != null) {
553 icon_rect.Width = owner.LargeImageList.ImageSize.Width;
554 icon_rect.Height = owner.LargeImageList.ImageSize.Height;
557 checkbox_rect.Y = icon_rect.Height - checkbox_rect.Height - 1;
559 if (text_size.Width <= (checkbox_rect.Width + icon_rect.Width)) {
560 icon_rect.X = checkbox_rect.Width + 1;
561 label_rect.X = icon_rect.X + (icon_rect.Width - text_size.Width) / 2;
562 label_rect.Y = Math.Max (checkbox_rect.Bottom, icon_rect.Bottom) + 2;
563 label_rect.Size = text_size;
565 int centerX = text_size.Width / 2;
566 icon_rect.X = centerX - icon_rect.Width / 2;
567 checkbox_rect.X = (icon_rect.X - checkbox_rect.Width);
568 label_rect.Y = Math.Max (checkbox_rect.Bottom, icon_rect.Bottom) + 2;
569 label_rect.Size = text_size;
572 item_rect = Rectangle.Union (icon_rect, label_rect);
573 total = Rectangle.Union (item_rect, checkbox_rect);
574 bounds.Size = total.Size;
579 label_rect = icon_rect = Rectangle.Empty;
580 icon_rect.X = checkbox_rect.Width + 1;
581 item_ht = Math.Max (owner.CheckBoxSize.Height, text_size.Height);
583 if (owner.SmallImageList != null) {
584 item_ht = Math.Max (item_ht, owner.SmallImageList.ImageSize.Height);
585 icon_rect.Width = owner.SmallImageList.ImageSize.Width;
586 icon_rect.Height = owner.SmallImageList.ImageSize.Height;
589 checkbox_rect.Y = icon_rect.Height - checkbox_rect.Height + 1;
590 label_rect.X = icon_rect.Right + 1;
591 label_rect.Width = text_size.Width;
592 label_rect.Height = icon_rect.Height = item_ht;
594 item_rect = Rectangle.Union (icon_rect, label_rect);
595 total = Rectangle.Union (item_rect, checkbox_rect);
596 bounds.Size = total.Size;
601 #endregion // Private Internal Methods
605 [DefaultProperty ("Text")]
606 [DesignTimeVisible (false)]
608 [ToolboxItem (false)]
609 [TypeConverter (typeof(ListViewSubItemConverter))]
610 public class ListViewSubItem
612 private Color back_color;
614 private Color fore_color;
615 internal ListViewItem owner;
618 #region Public Constructors
619 public ListViewSubItem ()
623 public ListViewSubItem (ListViewItem owner, string text)
624 : this (owner, text, ThemeEngine.Current.ColorWindowText,
625 ThemeEngine.Current.ColorWindow,
626 ThemeEngine.Current.DefaultFont)
630 public ListViewSubItem (ListViewItem owner, string text, Color foreColor,
631 Color backColor, Font font)
635 this.fore_color = foreColor;
636 this.back_color = backColor;
639 #endregion // Public Constructors
641 #region Public Instance Properties
642 public Color BackColor {
643 get { return back_color; }
655 else if (owner != null)
665 public Color ForeColor {
666 get { return fore_color; }
681 #endregion // Public Instance Properties
683 #region Public Methods
684 public void ResetStyle ()
686 font = ThemeEngine.Current.DefaultFont;
687 back_color = ThemeEngine.Current.DefaultControlBackColor;
688 fore_color = ThemeEngine.Current.DefaultControlForeColor;
692 public override string ToString ()
694 return string.Format ("ListViewSubItem {{0}}", text);
696 #endregion // Public Methods
699 #region Private Methods
700 private void Invalidate ()
702 if (owner == null || owner.owner == null)
705 owner.owner.Invalidate ();
707 #endregion // Private Methods
710 public class ListViewSubItemCollection : IList, ICollection, IEnumerable
712 private ArrayList list;
713 internal ListViewItem owner;
715 #region Public Constructors
716 public ListViewSubItemCollection (ListViewItem owner)
719 this.list = new ArrayList ();
721 #endregion // Public Constructors
723 #region Public Properties
725 public virtual int Count {
726 get { return list.Count; }
729 public virtual bool IsReadOnly {
730 get { return false; }
733 public ListViewSubItem this [int index] {
734 get { return (ListViewSubItem) list [index]; }
736 value.owner = this.owner;
737 list [index] = value;
741 bool ICollection.IsSynchronized {
742 get { return list.IsSynchronized; }
745 object ICollection.SyncRoot {
746 get { return list.SyncRoot; }
749 bool IList.IsFixedSize {
750 get { return list.IsFixedSize; }
753 object IList.this [int index] {
754 get { return this [index]; }
756 if (! (value is ListViewSubItem))
757 throw new ArgumentException ("Not of type ListViewSubItem", "value");
758 this [index] = (ListViewSubItem) value;
761 #endregion // Public Properties
763 #region Public Methods
764 public ListViewSubItem Add (ListViewSubItem item)
766 item.owner = this.owner;
771 public ListViewSubItem Add (string text)
773 ListViewSubItem item = new ListViewSubItem (this.owner, text);
778 public ListViewSubItem Add (string text, Color foreColor,
779 Color backColor, Font font)
781 ListViewSubItem item = new ListViewSubItem (this.owner, text,
782 foreColor, backColor, font);
787 public void AddRange (ListViewSubItem [] items)
790 foreach (ListViewSubItem item in items)
794 public void AddRange (string [] items)
797 foreach (string item in items)
801 public void AddRange (string [] items, Color foreColor,
802 Color backColor, Font font)
805 foreach (string item in items)
806 this.Add (item, foreColor, backColor, font);
809 public virtual void Clear ()
814 public bool Contains (ListViewSubItem item)
816 return list.Contains (item);
819 public virtual IEnumerator GetEnumerator ()
821 return list.GetEnumerator ();
824 void ICollection.CopyTo (Array dest, int index)
826 list.CopyTo (dest, index);
829 int IList.Add (object item)
831 if (! (item is ListViewSubItem)) {
832 throw new ArgumentException ("Not of type ListViewSubItem", "item");
835 ListViewSubItem sub_item = (ListViewSubItem) item;
836 sub_item.owner = this.owner;
837 return list.Add (sub_item);
840 bool IList.Contains (object subItem)
842 if (! (subItem is ListViewSubItem)) {
843 throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
846 return this.Contains ((ListViewSubItem) subItem);
849 int IList.IndexOf (object subItem)
851 if (! (subItem is ListViewSubItem)) {
852 throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
855 return this.IndexOf ((ListViewSubItem) subItem);
858 void IList.Insert (int index, object item)
860 if (! (item is ListViewSubItem)) {
861 throw new ArgumentException ("Not of type ListViewSubItem", "item");
864 this.Insert (index, (ListViewSubItem) item);
867 void IList.Remove (object item)
869 if (! (item is ListViewSubItem)) {
870 throw new ArgumentException ("Not of type ListViewSubItem", "item");
873 this.Remove ((ListViewSubItem) item);
876 public int IndexOf (ListViewSubItem subItem)
878 return list.IndexOf (subItem);
881 public void Insert (int index, ListViewSubItem item)
883 item.owner = this.owner;
884 list.Insert (index, item);
887 public void Remove (ListViewSubItem item)
892 public virtual void RemoveAt (int index)
894 list.RemoveAt (index);
896 #endregion // Public Methods
898 #endregion // Subclasses