/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListViewItem.cs
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
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (c) 2004 Novell, Inc. (http://www.novell.com)
- //
- // Author:
- // Ravindra (rkumar@novell.com)
- // Mike Kestner <mkestner@novell.com>
- // Daniel Nauck (dna(at)mono-project(dot)de)
- using System.Collections;
- using System.ComponentModel;
- using System.Drawing;
- using System.Runtime.Serialization;
- namespace System.Windows.Forms
- {
- [DefaultProperty ("Text")]
- [DesignTimeVisible (false)]
- [Serializable]
- [ToolboxItem (false)]
- [TypeConverter (typeof (ListViewItemConverter))]
- public class ListViewItem : ICloneable, ISerializable
- {
- #region Instance Variables
- private int image_index = -1;
- private bool is_checked = false;
- private int state_image_index = -1;
- private ListViewSubItemCollection sub_items;
- private object tag;
- private bool use_item_style = true;
- int display_index = -1; // actual position in ListView
- private ListViewGroup group = null;
- private string name = String.Empty;
- private string image_key = String.Empty;
- string tooltip_text = String.Empty;
- int indent_count;
- Point position = new Point (-1, -1); // cached to mimic .Net behaviour
- Rectangle bounds = Rectangle.Empty;
- Rectangle checkbox_rect; // calculated by CalcListViewItem method
- Rectangle icon_rect;
- Rectangle item_rect;
- Rectangle label_rect;
- ListView owner;
- Font font;
- Font hot_font; // cached font for hot tracking
- bool selected;
- internal int row;
- internal int col;
-
- #region UIA Framework: Methods, Properties and Events
- internal event EventHandler UIATextChanged;
-
- internal event LabelEditEventHandler UIASubItemTextChanged;
- internal void OnUIATextChanged ()
- {
- if (UIATextChanged != null)
- UIATextChanged (this, EventArgs.Empty);
- }
- internal void OnUIASubItemTextChanged (LabelEditEventArgs args)
- {
- //If our index is 0 we also generate TextChanged for the ListViewItem
- //because ListViewItem.Text is the same as ListViewItem.SubItems [0].Text
- if (args.Item == 0)
- OnUIATextChanged ();
- if (UIASubItemTextChanged != null)
- UIASubItemTextChanged (this, args);
- }
- #endregion // UIA Framework: Methods, Properties and Events
- #endregion Instance Variables
- #region Public Constructors
- public ListViewItem () : this (string.Empty)
- {
- }
- public ListViewItem (string text) : this (text, -1)
- {
- }
- public ListViewItem (string [] items) : this (items, -1)
- {
- }
- public ListViewItem (ListViewItem.ListViewSubItem [] subItems, int imageIndex)
- {
- this.sub_items = new ListViewSubItemCollection (this, null);
- for (int i = 0; i < subItems.Length; i++)
- sub_items.Add (subItems [i]);
- this.image_index = imageIndex;
- }
- public ListViewItem (string text, int imageIndex)
- {
- this.image_index = imageIndex;
- this.sub_items = new ListViewSubItemCollection (this, text);
- }
- public ListViewItem (string [] items, int imageIndex)
- {
- this.sub_items = new ListViewSubItemCollection (this, null);
- if (items != null) {
- for (int i = 0; i < items.Length; i++)
- sub_items.Add (new ListViewSubItem (this, items [i]));
- }
- this.image_index = imageIndex;
- }
- public ListViewItem (string [] items, int imageIndex, Color foreColor,
- Color backColor, Font font) : this (items, imageIndex)
- {
- ForeColor = foreColor;
- BackColor = backColor;
- this.font = font;
- }
- public ListViewItem(string[] items, string imageKey) : this(items)
- {
- this.ImageKey = imageKey;
- }
- public ListViewItem(string text, string imageKey) : this(text)
- {
- this.ImageKey = imageKey;
- }
- public ListViewItem(ListViewSubItem[] subItems, string imageKey)
- {
- this.sub_items = new ListViewSubItemCollection (this, null);
- for (int i = 0; i < subItems.Length; i++)
- this.sub_items.Add (subItems [i]);
- this.ImageKey = imageKey;
- }
- public ListViewItem(string[] items, string imageKey, Color foreColor,
- Color backColor, Font font) : this(items, imageKey)
- {
- ForeColor = foreColor;
- BackColor = backColor;
- this.font = font;
- }
- public ListViewItem(ListViewGroup group) : this()
- {
- Group = group;
- }
- public ListViewItem(string text, ListViewGroup group) : this(text)
- {
- Group = group;
- }
- public ListViewItem(string[] items, ListViewGroup group) : this(items)
- {
- Group = group;
- }
- public ListViewItem(ListViewSubItem[] subItems, int imageIndex, ListViewGroup group)
- : this(subItems, imageIndex)
- {
- Group = group;
- }
- public ListViewItem(ListViewSubItem[] subItems, string imageKey, ListViewGroup group)
- : this(subItems, imageKey)
- {
- Group = group;
- }
- public ListViewItem(string text, int imageIndex, ListViewGroup group)
- : this(text, imageIndex)
- {
- Group = group;
- }
- public ListViewItem(string text, string imageKey, ListViewGroup group)
- : this(text, imageKey)
- {
- Group = group;
- }
- public ListViewItem(string[] items, int imageIndex, ListViewGroup group)
- : this(items, imageIndex)
- {
- Group = group;
- }
- public ListViewItem(string[] items, string imageKey, ListViewGroup group)
- : this(items, imageKey)
- {
- Group = group;
- }
- public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor,
- Font font, ListViewGroup group)
- : this(items, imageIndex, foreColor, backColor, font)
- {
- Group = group;
- }
- public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor,
- Font font, ListViewGroup group)
- : this(items, imageKey, foreColor, backColor, font)
- {
- Group = group;
- }
- #endregion // Public Constructors
- protected ListViewItem (SerializationInfo info, StreamingContext context)
- {
- Deserialize (info, context);
- }
- #region Public Instance Properties
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public Color BackColor {
- get {
- if (sub_items.Count > 0)
- return sub_items[0].BackColor;
- if (owner != null)
- return owner.BackColor;
-
- return ThemeEngine.Current.ColorWindow;
- }
- set { SubItems [0].BackColor = value; }
- }
- [Browsable (false)]
- public Rectangle Bounds {
- get {
- return GetBounds (ItemBoundsPortion.Entire);
- }
- }
- [DefaultValue (false)]
- [RefreshProperties (RefreshProperties.Repaint)]
- public bool Checked {
- get { return is_checked; }
- set {
- if (is_checked == value)
- return;
-
- if (owner != null) {
- CheckState current_value = is_checked ? CheckState.Checked : CheckState.Unchecked;
- CheckState new_value = value ? CheckState.Checked : CheckState.Unchecked;
- ItemCheckEventArgs icea = new ItemCheckEventArgs (Index,
- new_value, current_value);
- owner.OnItemCheck (icea);
- if (new_value != current_value) {
- // force re-population of list
- owner.CheckedItems.Reset ();
- is_checked = new_value == CheckState.Checked;
- Invalidate ();
- ItemCheckedEventArgs args = new ItemCheckedEventArgs (this);
- owner.OnItemChecked (args);
- }
- } else
- is_checked = value;
- }
- }
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public bool Focused {
- get {
- if (owner == null)
- return false;
- // In virtual mode the checks are always done using indexes
- if (owner.VirtualMode)
- return Index == owner.focused_item_index;
- // Light check
- return owner.FocusedItem == this;
- }
- set {
- if (owner == null)
- return;
- if (Focused == value)
- return;
- ListViewItem prev_focused_item = owner.FocusedItem;
- if (prev_focused_item != null)
- prev_focused_item.UpdateFocusedState ();
-
- owner.focused_item_index = value ? Index : -1;
- if (value)
- owner.OnUIAFocusedItemChanged ();
- UpdateFocusedState ();
- }
- }
- [Localizable (true)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public Font Font {
- get {
- if (font != null)
- return font;
- else if (owner != null)
- return owner.Font;
- return ThemeEngine.Current.DefaultFont;
- }
- set {
- if (font == value)
- return;
- font = value;
- hot_font = null;
- if (owner != null)
- Layout ();
- Invalidate ();
- }
- }
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public Color ForeColor {
- get {
- if (sub_items.Count > 0)
- return sub_items[0].ForeColor;
- if (owner != null)
- return owner.ForeColor;
- return ThemeEngine.Current.ColorWindowText;
- }
- set { SubItems [0].ForeColor = value; }
- }
- [DefaultValue (-1)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
- typeof (System.Drawing.Design.UITypeEditor))]
- [Localizable (true)]
- [RefreshProperties (RefreshProperties.Repaint)]
- [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
- public int ImageIndex {
- get { return image_index; }
- set {
- if (value < -1)
- throw new ArgumentException ("Invalid ImageIndex. It must be greater than or equal to -1.");
-
- image_index = value;
- image_key = String.Empty;
- if (owner != null)
- Layout ();
- Invalidate ();
- }
- }
- [DefaultValue ("")]
- [LocalizableAttribute (true)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
- typeof (System.Drawing.Design.UITypeEditor))]
- [RefreshProperties (RefreshProperties.Repaint)]
- [TypeConverter (typeof (ImageKeyConverter))]
- public string ImageKey {
- get {
- return image_key;
- }
- set {
- image_key = value == null ? String.Empty : value;
- image_index = -1;
- if (owner != null)
- Layout ();
- Invalidate ();
- }
- }
- [Browsable (false)]
- public ImageList ImageList {
- get {
- if (owner == null)
- return null;
- else if (owner.View == View.LargeIcon)
- return owner.large_image_list;
- else
- return owner.small_image_list;
- }
- }
- [DefaultValue (0)]
- public int IndentCount {
- get {
- return indent_count;
- }
- set {
- if (value < 0)
- throw new ArgumentOutOfRangeException ("value");
- if (value == indent_count)
- return;
- indent_count = value;
- Invalidate ();
- }
- }
- [Browsable (false)]
- public int Index {
- get {
- if (owner == null)
- return -1;
- if (owner.VirtualMode)
- return display_index;
- if (display_index == -1)
- return owner.Items.IndexOf (this);
- return owner.GetItemIndex (display_index);
- }
- }
- [Browsable (false)]
- public ListView ListView {
- get { return owner; }
- }
- [Browsable (false)]
- [Localizable (true)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public string Name {
- get {
- return name;
- }
- set {
- name = value == null ? String.Empty : value;
- }
- }
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [Browsable (false)]
- public Point Position {
- get {
- if (owner != null && owner.VirtualMode)
- return owner.GetItemLocation (display_index);
- if (owner != null && !owner.IsHandleCreated)
- return new Point (-1, -1);
- return position;
- }
- set {
- if (owner == null || owner.View == View.Details || owner.View == View.List)
- return;
- if (owner.VirtualMode)
- throw new InvalidOperationException ();
- owner.ChangeItemLocation (display_index, value);
- }
- }
- // When ListView uses VirtualMode, selection state info
- // lives in the ListView, not in the item
- // Also, in VirtualMode we can't Reset() the selection
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public bool Selected {
- get {
- if (owner != null && owner.VirtualMode)
- return owner.SelectedIndices.Contains (Index);
- return selected;
- }
- set {
- if (selected == value && owner != null && !owner.VirtualMode)
- return;
- SetSelectedCore (value);
- }
- }
- // Expose this method as internal so we can force an update in the selection.
- internal void SetSelectedCore (bool value)
- {
- if (owner != null) {
- if (value && !owner.MultiSelect)
- owner.SelectedIndices.Clear ();
- if (owner.VirtualMode) {
- if (value)
- owner.SelectedIndices.InsertIndex (Index);
- else
- owner.SelectedIndices.RemoveIndex (Index);
- } else {
- selected = value;
- owner.SelectedIndices.Reset (); // force re-population of list
- }
- owner.OnItemSelectionChanged (new ListViewItemSelectionChangedEventArgs (this, Index, value));
- owner.OnSelectedIndexChanged ();
- Invalidate ();
- } else
- selected = value;
- }
- [DefaultValue (-1)]
- [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
- typeof (System.Drawing.Design.UITypeEditor))]
- [Localizable (true)]
- [RefreshProperties (RefreshProperties.Repaint)]
- [RelatedImageListAttribute ("ListView.StateImageList")]
- [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
- public int StateImageIndex {
- get { return state_image_index; }
- set {
- if (value < -1 || value > 14)
- throw new ArgumentOutOfRangeException ("Invalid StateImageIndex. It must be in the range of [-1, 14].");
- state_image_index = value;
- }
- }
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [Editor ("System.Windows.Forms.Design.ListViewSubItemCollectionEditor, " + Consts.AssemblySystem_Design,
- typeof (System.Drawing.Design.UITypeEditor))]
- public ListViewSubItemCollection SubItems {
- get {
- if (sub_items.Count == 0)
- this.sub_items.Add (string.Empty);
- return sub_items;
- }
- }
- [Bindable (true)]
- [DefaultValue (null)]
- [Localizable (false)]
- [TypeConverter (typeof (StringConverter))]
- public object Tag {
- get { return tag; }
- set { tag = value; }
- }
- [Localizable (true)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public string Text {
- get {
- if (this.sub_items.Count > 0)
- return this.sub_items [0].Text;
- else
- return string.Empty;
- }
- set {
- if (SubItems [0].Text == value)
- return;
- sub_items [0].Text = value;
- if (owner != null)
- Layout ();
- Invalidate ();
- //UIA Framework: Generates Text changed
- OnUIATextChanged ();
- }
- }
- [DefaultValue (true)]
- public bool UseItemStyleForSubItems {
- get { return use_item_style; }
- set { use_item_style = value; }
- }
- [LocalizableAttribute(true)]
- [DefaultValue (null)]
- public ListViewGroup Group {
- get { return this.group; }
- set {
- if (group != value) {
- if (value == null)
- group.Items.Remove (this);
- else
- value.Items.Add (this);
-
- group = value;
- }
- }
- }
- [DefaultValue ("")]
- public string ToolTipText {
- get {
- return tooltip_text;
- }
- set {
- if (value == null)
- value = String.Empty;
- tooltip_text = value;
- }
- }
- #endregion // Public Instance Properties
- #region Public Instance Methods
- public void BeginEdit ()
- {
- if (owner != null && owner.LabelEdit) {
- owner.item_control.BeginEdit (this);
- }
- // FIXME: TODO
- // if (owner != null && owner.LabelEdit
- // && owner.Activation == ItemActivation.Standard)
- // allow editing
- // else
- // throw new InvalidOperationException ();
- }
- public virtual object Clone ()
- {
- ListViewItem clone = new ListViewItem ();
- clone.image_index = this.image_index;
- clone.is_checked = this.is_checked;
- clone.selected = this.selected;
- clone.font = this.font;
- clone.state_image_index = this.state_image_index;
- clone.sub_items = new ListViewSubItemCollection (this, null);
-
- foreach (ListViewSubItem subItem in this.sub_items)
- clone.sub_items.Add (subItem.Text, subItem.ForeColor,
- subItem.BackColor, subItem.Font);
- clone.tag = this.tag;
- clone.use_item_style = this.use_item_style;
- clone.owner = null;
- clone.name = name;
- clone.tooltip_text = tooltip_text;
- return clone;
- }
- public virtual void EnsureVisible ()
- {
- if (this.owner != null) {
- owner.EnsureVisible (owner.Items.IndexOf (this));
- }
- }
- public ListViewItem FindNearestItem (SearchDirectionHint searchDirection)
- {
- if (owner == null)
- return null;
- Point loc = owner.GetItemLocation (display_index);
- return owner.FindNearestItem (searchDirection, loc);
- }
- public Rectangle GetBounds (ItemBoundsPortion portion)
- {
- if (owner == null)
- return Rectangle.Empty;
-
- Rectangle rect;
- switch (portion) {
- case ItemBoundsPortion.Icon:
- rect = icon_rect;
- break;
- case ItemBoundsPortion.Label:
- rect = label_rect;
- break;
- case ItemBoundsPortion.ItemOnly:
- rect = item_rect;
- break;
- case ItemBoundsPortion.Entire:
- rect = bounds;
- break;
- default:
- throw new ArgumentException ("Invalid value for portion.");
- }
- Point item_loc = owner.GetItemLocation (DisplayIndex);
- rect.X += item_loc.X;
- rect.Y += item_loc.Y;
- return rect;
- }
- void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
- {
- Serialize (info, context);
- }
- public ListViewSubItem GetSubItemAt (int x, int y)
- {
- if (owner != null && owner.View != View.Details)
- return null;
- foreach (ListViewSubItem sub_item in sub_items)
- if (sub_item.Bounds.Contains (x, y))
- return sub_item;
- return null;
- }
- public virtual void Remove ()
- {
- if (owner == null)
- return;
- owner.item_control.CancelEdit (this);
- owner.Items.Remove (this);
- owner = null;
- }
- public override string ToString ()
- {
- return string.Format ("ListViewItem: {0}", this.Text);
- }
- #endregion // Public Instance Methods
- #region Protected Methods
- protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
- {
- sub_items = new ListViewSubItemCollection (this, null);
- int sub_items_count = 0;
- foreach (SerializationEntry entry in info) {
- switch (entry.Name) {
- case "Text":
- sub_items.Add ((string)entry.Value);
- break;
- case "Font":
- font = (Font)entry.Value;
- break;
- case "Checked":
- is_checked = (bool)entry.Value;
- break;
- case "ImageIndex":
- image_index = (int)entry.Value;
- break;
- case "StateImageIndex":
- state_image_index = (int)entry.Value;
- break;
- case "UseItemStyleForSubItems":
- use_item_style = (bool)entry.Value;
- break;
- case "SubItemCount":
- sub_items_count = (int)entry.Value;
- break;
- case "Group":
- group = (ListViewGroup)entry.Value;
- break;
- case "ImageKey":
- if (image_index == -1)
- image_key = (string)entry.Value;
- break;
- }
- }
- Type subitem_type = typeof (ListViewSubItem);
- if (sub_items_count > 0) {
- sub_items.Clear (); // .net fixup
- Text = info.GetString ("Text");
- for (int i = 0; i < sub_items_count - 1; i++)
- sub_items.Add ((ListViewSubItem)info.GetValue ("SubItem" + (i + 1), subitem_type));
- }
- // After any sub item has been added.
- ForeColor = (Color)info.GetValue ("ForeColor", typeof (Color));
- BackColor = (Color)info.GetValue ("BackColor", typeof (Color));
- }
- protected virtual void Serialize (SerializationInfo info, StreamingContext context)
- {
- info.AddValue ("Text", Text);
- info.AddValue ("Font", Font);
- info.AddValue ("ImageIndex", image_index);
- info.AddValue ("Checked", is_checked);
- info.AddValue ("StateImageIndex", state_image_index);
- info.AddValue ("UseItemStyleForSubItems", use_item_style);
- info.AddValue ("BackColor", BackColor);
- info.AddValue ("ForeColor", ForeColor);
- info.AddValue ("ImageKey", image_key);
- if (group != null)
- info.AddValue ("Group", group);
- if (sub_items.Count > 1) {
- info.AddValue ("SubItemCount", sub_items.Count);
- for (int i = 1; i < sub_items.Count; i++) {
- info.AddValue ("SubItem" + i, sub_items [i]);
- }
- }
- }
- #endregion // Protected Methods
- #region Private Internal Methods
- internal Rectangle CheckRectReal {
- get {
- Rectangle rect = checkbox_rect;
- Point item_loc = owner.GetItemLocation (DisplayIndex);
- rect.X += item_loc.X;
- rect.Y += item_loc.Y;
- return rect;
- }
- }
-
- Rectangle text_bounds;
- internal Rectangle TextBounds {
- get {
- // Call Layout() if it hasn't been called before.
- if (owner.VirtualMode && bounds == new Rectangle (-1, -1, -1, -1))
- Layout ();
- Rectangle result = text_bounds;
- Point loc = owner.GetItemLocation (DisplayIndex);
- result.X += loc.X;
- result.Y += loc.Y;
- return result;
- }
- }
- internal int DisplayIndex {
- get {
- // Special case for Details view
- // and no columns (which means no Layout at all)
- if (display_index == -1)
- return owner.Items.IndexOf (this);
- return display_index;
- }
- set {
- display_index = value;
- }
- }
- internal bool Hot {
- get {
- return Index == owner.HotItemIndex;
- }
- }
- internal Font HotFont {
- get {
- if (hot_font == null)
- hot_font = new Font (Font, Font.Style | FontStyle.Underline);
- return hot_font;
- }
- }
- internal ListView Owner {
- set {
- if (owner == value)
- return;
- owner = value;
- }
- }
- internal void SetGroup (ListViewGroup group)
- {
- this.group = group;
- }
- internal void SetPosition (Point position)
- {
- this.position = position;
- }
- // When focus changed, we need to invalidate area
- // with previous layout and with the new one
- void UpdateFocusedState ()
- {
- if (owner != null) {
- Invalidate ();
- Layout ();
- Invalidate ();
- }
- }
- internal void Invalidate ()
- {
- if (owner == null || owner.item_control == null || owner.updating)
- return;
- // Add some padding to bounds (focused extra space, selection)
- Rectangle rect = Bounds;
- rect.Inflate (1, 1);
- owner.item_control.Invalidate (rect);
- }
- internal void Layout ()
- {
- if (owner == null)
- return;
- int item_ht;
- Rectangle total;
- Size text_size = owner.text_size;
-
- checkbox_rect = Rectangle.Empty;
- if (owner.CheckBoxes)
- checkbox_rect.Size = owner.CheckBoxSize;
- switch (owner.View) {
- case View.Details:
- // LAMESPEC: MSDN says, "In all views except the details
- // view of the ListView, this value specifies the same
- // bounding rectangle as the Entire value." Actually, it
- // returns same bounding rectangles for Item and Entire
- // values in the case of Details view.
- int x_offset = 0;
- if (owner.SmallImageList != null)
- x_offset = indent_count * owner.SmallImageList.ImageSize.Width;
- // Handle reordered column
- if (owner.Columns.Count > 0)
- checkbox_rect.X = owner.Columns[0].Rect.X + x_offset;
- icon_rect = label_rect = Rectangle.Empty;
- icon_rect.X = checkbox_rect.Right + 2;
- item_ht = owner.ItemSize.Height;
- if (owner.SmallImageList != null)
- icon_rect.Width = owner.SmallImageList.ImageSize.Width;
- label_rect.Height = icon_rect.Height = item_ht;
- checkbox_rect.Y = item_ht - checkbox_rect.Height;
- label_rect.X = icon_rect.Width > 0 ? icon_rect.Right + 1 : icon_rect.Right;
- if (owner.Columns.Count > 0)
- label_rect.Width = owner.Columns[0].Wd - label_rect.X + checkbox_rect.X;
- else
- label_rect.Width = text_size.Width;
- SizeF text_sz = TextRenderer.MeasureString (Text, Font);
- text_bounds = label_rect;
- text_bounds.Width = (int) text_sz.Width;
- item_rect = total = Rectangle.Union
- (Rectangle.Union (checkbox_rect, icon_rect), label_rect);
- bounds.Size = total.Size;
- item_rect.Width = 0;
- bounds.Width = 0;
- for (int i = 0; i < owner.Columns.Count; i++) {
- item_rect.Width += owner.Columns [i].Wd;
- bounds.Width += owner.Columns [i].Wd;
- }
- // Bounds for sub items
- int n = Math.Min (owner.Columns.Count, sub_items.Count);
- for (int i = 0; i < n; i++) {
- Rectangle col_rect = owner.Columns [i].Rect;
- sub_items [i].SetBounds (col_rect.X, 0, col_rect.Width, item_ht);
- }
- break;
- case View.LargeIcon:
- label_rect = icon_rect = Rectangle.Empty;
- SizeF sz = TextRenderer.MeasureString (Text, Font);
- if ((int) sz.Width > text_size.Width) {
- if (Focused && owner.InternalContainsFocus) {
- int text_width = text_size.Width;
- StringFormat format = new StringFormat ();
- format.Alignment = StringAlignment.Center;
- sz = TextRenderer.MeasureString (Text, Font, text_width, format);
- text_size.Height = (int) sz.Height;
- } else
- text_size.Height = 2 * (int) sz.Height;
- }
- if (owner.LargeImageList != null) {
- icon_rect.Width = owner.LargeImageList.ImageSize.Width;
- icon_rect.Height = owner.LargeImageList.ImageSize.Height;
- }
- if (checkbox_rect.Height > icon_rect.Height)
- icon_rect.Y = checkbox_rect.Height - icon_rect.Height;
- else
- checkbox_rect.Y = icon_rect.Height - checkbox_rect.Height;
- if (text_size.Width <= icon_rect.Width) {
- icon_rect.X = checkbox_rect.Width + 1;
- label_rect.X = icon_rect.X + (icon_rect.Width - text_size.Width) / 2;
- label_rect.Y = icon_rect.Bottom + 2;
- label_rect.Size = text_size;
- } else {
- int centerX = text_size.Width / 2;
- icon_rect.X = checkbox_rect.Width + 1 + centerX - icon_rect.Width / 2;
- label_rect.X = checkbox_rect.Width + 1;
- label_rect.Y = icon_rect.Bottom + 2;
- label_rect.Size = text_size;
- }
- item_rect = Rectangle.Union (icon_rect, label_rect);
- total = Rectangle.Union (item_rect, checkbox_rect);
- bounds.Size = total.Size;
- break;
- case View.List:
- case View.SmallIcon:
- label_rect = icon_rect = Rectangle.Empty;
- icon_rect.X = checkbox_rect.Width + 1;
- item_ht = Math.Max (owner.CheckBoxSize.Height, text_size.Height);
- if (owner.SmallImageList != null) {
- item_ht = Math.Max (item_ht, owner.SmallImageList.ImageSize.Height);
- icon_rect.Width = owner.SmallImageList.ImageSize.Width;
- icon_rect.Height = owner.SmallImageList.ImageSize.Height;
- }
- checkbox_rect.Y = item_ht - checkbox_rect.Height;
- label_rect.X = icon_rect.Right + 1;
- label_rect.Width = text_size.Width;
- label_rect.Height = icon_rect.Height = item_ht;
- item_rect = Rectangle.Union (icon_rect, label_rect);
- total = Rectangle.Union (item_rect, checkbox_rect);
- bounds.Size = total.Size;
- break;
- case View.Tile:
- if (!Application.VisualStylesEnabled)
- goto case View.LargeIcon;
- label_rect = icon_rect = Rectangle.Empty;
- if (owner.LargeImageList != null) {
- icon_rect.Width = owner.LargeImageList.ImageSize.Width;
- icon_rect.Height = owner.LargeImageList.ImageSize.Height;
- }
- int separation = 2;
- SizeF tsize = TextRenderer.MeasureString (Text, Font);
- int main_item_height = (int) Math.Ceiling (tsize.Height);
- int main_item_width = (int) Math.Ceiling (tsize.Width);
- sub_items [0].bounds.Height = main_item_height;
- // Set initial values for subitem's layout
- int total_height = main_item_height;
- int max_subitem_width = main_item_width;
-
- int count = Math.Min (owner.Columns.Count, sub_items.Count);
- for (int i = 1; i < count; i++) { // Ignore first column and first subitem
- ListViewSubItem sub_item = sub_items [i];
- if (sub_item.Text == null || sub_item.Text.Length == 0)
- continue;
- tsize = TextRenderer.MeasureString (sub_item.Text, sub_item.Font);
-
- int width = (int)Math.Ceiling (tsize.Width);
- if (width > max_subitem_width)
- max_subitem_width = width;
-
- int height = (int)Math.Ceiling (tsize.Height);
- total_height += height + separation;
-
- sub_item.bounds.Height = height;
- }
- max_subitem_width = Math.Min (max_subitem_width, owner.TileSize.Width - (icon_rect.Width + 4));
- label_rect.X = icon_rect.Right + 4;
- label_rect.Y = owner.TileSize.Height / 2 - total_height / 2;
- label_rect.Width = max_subitem_width;
- label_rect.Height = total_height;
-
- // Main item - always set bounds for it
- sub_items [0].SetBounds (label_rect.X, label_rect.Y, max_subitem_width, sub_items [0].bounds.Height);
- // Second pass to assign bounds for every sub item
- int current_y = sub_items [0].bounds.Bottom + separation;
- for (int j = 1; j < count; j++) {
- ListViewSubItem sub_item = sub_items [j];
- if (sub_item.Text == null || sub_item.Text.Length == 0)
- continue;
- sub_item.SetBounds (label_rect.X, current_y, max_subitem_width, sub_item.bounds.Height);
- current_y += sub_item.Bounds.Height + separation;
- }
-
- item_rect = Rectangle.Union (icon_rect, label_rect);
- bounds.Size = item_rect.Size;
- break;
- }
-
- }
- #endregion // Private Internal Methods
- #region Subclasses
- [DefaultProperty ("Text")]
- [DesignTimeVisible (false)]
- [Serializable]
- [ToolboxItem (false)]
- [TypeConverter (typeof(ListViewSubItemConverter))]
- public class ListViewSubItem
- {
- [NonSerialized]
- internal ListViewItem owner;
- private string text = string.Empty;
- private string name;
- private object userData;
- private SubItemStyle style;
- [NonSerialized]
- internal Rectangle bounds;
-
- #region UIA Framework: Methods, Properties and Events
-
- [field:NonSerialized]
- internal event EventHandler UIATextChanged;
- private void OnUIATextChanged ()
- {
- if (UIATextChanged != null)
- UIATextChanged (this, EventArgs.Empty);
- }
- #endregion // UIA Framework: Methods, Properties and Events
-
- #region Public Constructors
- public ListViewSubItem ()
- : this (null, string.Empty, Color.Empty,
- Color.Empty, null)
- {
- }
- public ListViewSubItem (ListViewItem owner, string text)
- : this (owner, text, Color.Empty,
- Color.Empty, null)
- {
- }
- public ListViewSubItem (ListViewItem owner, string text, Color foreColor,
- Color backColor, Font font)
- {
- this.owner = owner;
- Text = text;
- this.style = new SubItemStyle (foreColor,
- backColor, font);
- }
- #endregion // Public Constructors
- #region Public Instance Properties
- public Color BackColor {
- get {
- if (style.backColor != Color.Empty)
- return style.backColor;
- if (this.owner != null && this.owner.ListView != null)
- return this.owner.ListView.BackColor;
- return ThemeEngine.Current.ColorWindow;
- }
- set {
- style.backColor = value;
- Invalidate ();
- }
- }
- [Browsable (false)]
- public Rectangle Bounds {
- get {
- Rectangle retval = bounds;
- if (owner != null) {
- retval.X += owner.Bounds.X;
- retval.Y += owner.Bounds.Y;
- }
- return retval;
- }
- }
- [Localizable (true)]
- public Font Font {
- get {
- if (style.font != null)
- return style.font;
- else if (owner != null)
- return owner.Font;
- return ThemeEngine.Current.DefaultFont;
- }
- set {
- if (style.font == value)
- return;
- style.font = value;
- Invalidate ();
- }
- }
- public Color ForeColor {
- get {
- if (style.foreColor != Color.Empty)
- return style.foreColor;
- if (this.owner != null && this.owner.ListView != null)
- return this.owner.ListView.ForeColor;
- return ThemeEngine.Current.ColorWindowText;
- }
- set {
- style.foreColor = value;
- Invalidate ();
- }
- }
- [Localizable (true)]
- public string Name {
- get {
- if (name == null)
- return string.Empty;
- return name;
- }
- set {
- name = value;
- }
- }
- [TypeConverter (typeof (StringConverter))]
- [BindableAttribute (true)]
- [DefaultValue (null)]
- [Localizable (false)]
- public object Tag {
- get {
- return userData;
- }
- set {
- userData = value;
- }
- }
- [Localizable (true)]
- public string Text {
- get { return text; }
- set {
- if(text == value)
- return;
- if(value == null)
- text = string.Empty;
- else
- text = value;
- Invalidate ();
- // UIA Framework: Generates SubItem TextChanged
- OnUIATextChanged ();
- }
- }
- #endregion // Public Instance Properties
- #region Public Methods
- public void ResetStyle ()
- {
- style.Reset ();
- Invalidate ();
- }
- public override string ToString ()
- {
- return string.Format ("ListViewSubItem {{0}}", text);
- }
- #endregion // Public Methods
- #region Private Methods
- private void Invalidate ()
- {
- if (owner == null || owner.owner == null)
- return;
- owner.Invalidate ();
- }
- [OnDeserialized]
- void OnDeserialized (StreamingContext context)
- {
- name = null;
- userData = null;
- }
- internal int Height {
- get {
- return bounds.Height;
- }
- }
- internal void SetBounds (int x, int y, int width, int height)
- {
- bounds = new Rectangle (x, y, width, height);
- }
- #endregion // Private Methods
- [Serializable]
- class SubItemStyle
- {
- public SubItemStyle ()
- {
- }
- public SubItemStyle (Color foreColor, Color backColor, Font font)
- {
- this.foreColor = foreColor;
- this.backColor = backColor;
- this.font = font;
- }
- public void Reset ()
- {
- foreColor = Color.Empty;
- backColor = Color.Empty;
- font = null;
- }
- public Color backColor;
- public Color foreColor;
- public Font font;
- }
- }
- public class ListViewSubItemCollection : IList, ICollection, IEnumerable
- {
- private ArrayList list;
- internal ListViewItem owner;
- #region Public Constructors
- public ListViewSubItemCollection (ListViewItem owner) : this (owner, owner.Text)
- {
- }
- #endregion // Public Constructors
- internal ListViewSubItemCollection (ListViewItem owner, string text)
- {
- this.owner = owner;
- this.list = new ArrayList ();
- if (text != null)
- Add (text);
- }
- #region Public Properties
- [Browsable (false)]
- public int Count {
- get { return list.Count; }
- }
- public bool IsReadOnly {
- get { return false; }
- }
- public ListViewSubItem this [int index] {
- get { return (ListViewSubItem) list [index]; }
- set {
- value.owner = owner;
- list [index] = value;
- owner.Layout ();
- owner.Invalidate ();
- }
- }
- public virtual ListViewSubItem this [string key] {
- get {
- int idx = IndexOfKey (key);
- if (idx == -1)
- return null;
- return (ListViewSubItem) list [idx];
- }
- }
- bool ICollection.IsSynchronized {
- get { return list.IsSynchronized; }
- }
- object ICollection.SyncRoot {
- get { return list.SyncRoot; }
- }
- bool IList.IsFixedSize {
- get { return list.IsFixedSize; }
- }
- object IList.this [int index] {
- get { return this [index]; }
- set {
- if (! (value is ListViewSubItem))
- throw new ArgumentException ("Not of type ListViewSubItem", "value");
- this [index] = (ListViewSubItem) value;
- }
- }
- #endregion // Public Properties
- #region Public Methods
- public ListViewSubItem Add (ListViewSubItem item)
- {
- AddSubItem (item);
- owner.Layout ();
- owner.Invalidate ();
- return item;
- }
- public ListViewSubItem Add (string text)
- {
- ListViewSubItem item = new ListViewSubItem (owner, text);
- return Add (item);
- }
- public ListViewSubItem Add (string text, Color foreColor,
- Color backColor, Font font)
- {
- ListViewSubItem item = new ListViewSubItem (owner, text,
- foreColor, backColor, font);
- return Add (item);
- }
- public void AddRange (ListViewSubItem [] items)
- {
- if (items == null)
- throw new ArgumentNullException ("items");
- foreach (ListViewSubItem item in items) {
- if (item == null)
- continue;
- AddSubItem (item);
- }
- owner.Layout ();
- owner.Invalidate ();
- }
- public void AddRange (string [] items)
- {
- if (items == null)
- throw new ArgumentNullException ("items");
- foreach (string item in items) {
- if (item == null)
- continue;
- AddSubItem (new ListViewSubItem (owner, item));
- }
- owner.Layout ();
- owner.Invalidate ();
- }
- public void AddRange (string [] items, Color foreColor,
- Color backColor, Font font)
- {
- if (items == null)
- throw new ArgumentNullException ("items");
- foreach (string item in items) {
- if (item == null)
- continue;
- AddSubItem (new ListViewSubItem (owner, item, foreColor, backColor, font));
- }
- owner.Layout ();
- owner.Invalidate ();
- }
- void AddSubItem (ListViewSubItem subItem)
- {
- subItem.owner = owner;
- list.Add (subItem);
- //UIA Framework
- subItem.UIATextChanged += OnUIASubItemTextChanged;
- }
- public void Clear ()
- {
- list.Clear ();
- }
- public bool Contains (ListViewSubItem subItem)
- {
- return list.Contains (subItem);
- }
- public virtual bool ContainsKey (string key)
- {
- return IndexOfKey (key) != -1;
- }
- public IEnumerator GetEnumerator ()
- {
- return list.GetEnumerator ();
- }
- void ICollection.CopyTo (Array dest, int index)
- {
- list.CopyTo (dest, index);
- }
- int IList.Add (object item)
- {
- if (! (item is ListViewSubItem)) {
- throw new ArgumentException ("Not of type ListViewSubItem", "item");
- }
- ListViewSubItem sub_item = (ListViewSubItem) item;
- sub_item.owner = this.owner;
- //UIA Framework
- sub_item.UIATextChanged += OnUIASubItemTextChanged;
- return list.Add (sub_item);
- }
- bool IList.Contains (object subItem)
- {
- if (! (subItem is ListViewSubItem)) {
- throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
- }
- return this.Contains ((ListViewSubItem) subItem);
- }
- int IList.IndexOf (object subItem)
- {
- if (! (subItem is ListViewSubItem)) {
- throw new ArgumentException ("Not of type ListViewSubItem", "subItem");
- }
- return this.IndexOf ((ListViewSubItem) subItem);
- }
- void IList.Insert (int index, object item)
- {
- if (! (item is ListViewSubItem)) {
- throw new ArgumentException ("Not of type ListViewSubItem", "item");
- }
- this.Insert (index, (ListViewSubItem) item);
- }
- void IList.Remove (object item)
- {
- if (! (item is ListViewSubItem)) {
- throw new ArgumentException ("Not of type ListViewSubItem", "item");
- }
- this.Remove ((ListViewSubItem) item);
- }
- public int IndexOf (ListViewSubItem subItem)
- {
- return list.IndexOf (subItem);
- }
- public virtual int IndexOfKey (string key)
- {
- if (key == null || key.Length == 0)
- return -1;
- for (int i = 0; i < list.Count; i++) {
- ListViewSubItem l = (ListViewSubItem) list [i];
- if (String.Compare (l.Name, key, true) == 0)
- return i;
- }
- return -1;
- }
- public void Insert (int index, ListViewSubItem item)
- {
- item.owner = this.owner;
- list.Insert (index, item);
- owner.Layout ();
- owner.Invalidate ();
- //UIA Framework
- item.UIATextChanged += OnUIASubItemTextChanged;
- }
- public void Remove (ListViewSubItem item)
- {
- list.Remove (item);
- owner.Layout ();
- owner.Invalidate ();
- //UIA Framework
- item.UIATextChanged -= OnUIASubItemTextChanged;
- }
- public virtual void RemoveByKey (string key)
- {
- int idx = IndexOfKey (key);
- if (idx != -1)
- RemoveAt (idx);
- }
- public void RemoveAt (int index)
- {
- //UIA Framework
- if (index >= 0 && index < list.Count)
- ((ListViewSubItem) list [index]).UIATextChanged -= OnUIASubItemTextChanged;
- list.RemoveAt (index);
- }
- #endregion // Public Methods
- #region UIA Event Handler
-
- private void OnUIASubItemTextChanged (object sender, EventArgs args)
- {
- owner.OnUIASubItemTextChanged (new LabelEditEventArgs (list.IndexOf (sender)));
- }
- #endregion
- }
- #endregion // Subclasses
- }
- }