// Ravindra Kumar (rkumar@novell.com)
// Jordi Mas i Hernandez, jordi@ximian.com
// Mike Kestner (mkestner@novell.com)
+// Daniel Nauck (dna(at)mono-project(dot)de)
//
// TODO:
// - Feedback for item activation, change in cursor types as mouse moves.
using System.Drawing;
using System.Runtime.InteropServices;
using System.Globalization;
+#if NET_2_0
+using System.Collections.Generic;
+#endif
namespace System.Windows.Forms
{
[DefaultEvent ("SelectedIndexChanged")]
[DefaultProperty ("Items")]
[Designer ("System.Windows.Forms.Design.ListViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+ [ClassInterface (ClassInterfaceType.AutoDispatch)]
+ [ComVisible (true)]
+ [Docking (DockingBehavior.Ask)]
+#endif
public class ListView : Control
{
private ItemActivation activation = ItemActivation.Standard;
private bool hover_selection = false;
private IComparer item_sorter;
private readonly ListViewItemCollection items;
+#if NET_2_0
+ private readonly ListViewGroupCollection groups;
+ private bool show_groups = true;
+#endif
private bool label_edit = false;
private bool label_wrap = true;
private bool multiselect = true;
private string keysearch_text;
static private readonly int keysearch_keydelay = 1000;
private int[] reordered_column_indices;
+#if NET_2_0
+ private Size tile_size;
+#endif
// internal variables
internal ImageList large_image_list;
{
background_color = ThemeEngine.Current.ColorWindow;
items = new ListViewItemCollection (this);
+#if NET_2_0
+ groups = new ListViewGroupCollection (this);
+#endif
checked_indices = new CheckedIndexCollection (this);
checked_items = new CheckedListViewItemCollection (this);
columns = new ColumnHeaderCollection (this);
get {
return focused_item;
}
+#if NET_2_0
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
public override Color ForeColor {
}
#if NET_2_0
- [MonoTODO("Implement")]
+ [DefaultValue(true)]
public bool ShowGroups {
- get {
- return false;
+ get { return show_groups; }
+ set
+ {
+ if (show_groups != value)
+ {
+ show_groups = value;
+ Redraw(true);
+ }
}
+ }
- set {
- }
+ [LocalizableAttribute (true)]
+ [MergableProperty (false)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+ public ListViewGroupCollection Groups {
+ get { return groups; }
}
#endif
}
}
+#if NET_2_0
+ [Browsable (true)]
+ public Size TileSize {
+ get {
+ return tile_size;
+ }
+ set {
+ if (value.Width <= 0 || value.Height <= 0)
+ throw new ArgumentOutOfRangeException ("value");
+
+ tile_size = value;
+ Redraw (true);
+ }
+ }
+#endif
+
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public ListViewItem TopItem {
return null;
}
}
+#if NET_2_0
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
#if NET_2_0
- [MonoTODO("Implement")]
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
+ [DefaultValue (true)]
+ [Browsable (false)]
+ [MonoInternalNote ("Stub, not implemented")]
public bool UseCompatibleStateImageBehavior {
get {
return false;
}
-
set {
}
}
get {
for (int i = FirstVisibleIndex; i < Items.Count; i++) {
if (View == View.List || Alignment == ListViewAlignment.Left) {
- if (Items[i].Bounds.X > ClientRectangle.Right)
+ if (Items[i].Bounds.X > item_control.ClientRectangle.Right)
return i - 1;
} else {
- if (Items[i].Bounds.Y > ClientRectangle.Bottom)
+ if (Items[i].Bounds.Y > item_control.ClientRectangle.Bottom)
return i - 1;
}
}
Refresh ();
}
+ const int text_padding = 15;
+
internal Size GetChildColumnSize (int index)
{
Size ret_size = Size.Empty;
if (col.Width == -2) { // autosize = max(items, columnheader)
Size size = Size.Ceiling (this.DeviceContext.MeasureString
(col.Text, this.Font));
+ size.Width += text_padding;
ret_size = BiggestItem (index);
if (size.Width > ret_size.Width)
ret_size = size;
}
}
+ ret_size.Height += text_padding;
+
// adjust the size for icon and checkbox for 0th column
if (index == 0) {
ret_size.Width += (this.CheckBoxSize.Width + 4);
item_control.Width -= v_scroll.Width;
}
}
+
+#if NET_2_0
+ internal int GetReorderedColumnIndex (ColumnHeader column)
+ {
+ if (reordered_column_indices == null)
+ return column.Index;
+
+ for (int i = 0; i < Columns.Count; i++)
+ if (reordered_column_indices [i] == column.Index)
+ return i;
+
+ return -1;
+ }
+#endif
- ColumnHeader GetReorderedColumn (int index)
+ internal ColumnHeader GetReorderedColumn (int index)
{
if (reordered_column_indices == null)
return Columns [index];
return Columns [reordered_column_indices [index]];
}
- void ReorderColumn (ColumnHeader col, int index)
+ internal void ReorderColumn (ColumnHeader col, int index)
{
+#if NET_2_0
+ ColumnReorderedEventHandler eh = (ColumnReorderedEventHandler) (Events [ColumnReorderedEvent]);
+ if (eh != null){
+ ColumnReorderedEventArgs args = new ColumnReorderedEventArgs (col.Index, index, col);
+
+ eh (this, args);
+ if (args.Cancel){
+ header_control.Invalidate ();
+ item_control.Invalidate ();
+ return;
+ }
+ }
+#endif
if (reordered_column_indices == null) {
reordered_column_indices = new int [Columns.Count];
for (int i = 0; i < Columns.Count; i++)
}
}
+#if NET_2_0
+ Size TileItemSize {
+ get {
+ // Calculate tile size if needed
+ // It appears that using Font.Size instead of a SizeF value can give us
+ // a slightly better approach to the proportions defined in .Net
+ if (tile_size == Size.Empty) {
+ int image_w = LargeImageList == null ? 0 : LargeImageList.ImageSize.Width;
+ int image_h = LargeImageList == null ? 0 : LargeImageList.ImageSize.Height;
+ int w = (int)Font.Size * ThemeEngine.Current.ListViewTileWidthFactor + image_w + 4;
+ int h = Math.Max ((int)Font.Size * ThemeEngine.Current.ListViewTileHeightFactor, image_h);
+
+ tile_size = new Size (w, h);
+ }
+
+ return tile_size;
+ }
+ }
+#endif
+
int rows;
int cols;
ListViewItem[,] item_matrix;
- void LayoutIcons (bool large_icons, bool left_aligned, int x_spacing, int y_spacing)
+ void LayoutIcons (Size item_size, bool left_aligned, int x_spacing, int y_spacing)
{
header_control.Visible = false;
header_control.Size = Size.Empty;
if (items.Count == 0)
return;
- Size sz = large_icons ? LargeIconItemSize : SmallIconItemSize;
-
+ Size sz = item_size;
Rectangle area = ClientRectangle;
if (left_aligned) {
break;
case View.SmallIcon:
- LayoutIcons (false, alignment == ListViewAlignment.Left, 4, 2);
+ LayoutIcons (SmallIconItemSize, alignment == ListViewAlignment.Left, 4, 2);
break;
case View.LargeIcon:
- LayoutIcons (true, alignment == ListViewAlignment.Left,
+ LayoutIcons (LargeIconItemSize, alignment == ListViewAlignment.Left,
ThemeEngine.Current.ListViewHorizontalSpacing,
ThemeEngine.Current.ListViewVerticalSpacing);
break;
case View.List:
- LayoutIcons (false, true, 4, 2);
+ LayoutIcons (SmallIconItemSize, true, 4, 2);
+ break;
+#if NET_2_0
+ case View.Tile:
+ LayoutIcons (TileItemSize, alignment == ListViewAlignment.Left,
+ ThemeEngine.Current.ListViewHorizontalSpacing,
+ ThemeEngine.Current.ListViewVerticalSpacing);
break;
+#endif
}
CalculateScrollBars ();
int result = -1;
if (View == View.Details) {
- if (key == Keys.Up)
+ switch (key) {
+ case Keys.Up:
result = FocusedItem.Index - 1;
- else if (key == Keys.Down) {
+ break;
+ case Keys.Down:
result = FocusedItem.Index + 1;
if (result == items.Count)
result = -1;
+ break;
+ case Keys.PageDown:
+ int last_index = LastVisibleIndex;
+ if (Items [last_index].Bounds.Bottom > item_control.ClientRectangle.Bottom)
+ last_index--;
+ if (FocusedItem.Index == last_index) {
+ if (FocusedItem.Index < Items.Count - 1) {
+ int page_size = item_control.Height / items [0].Bounds.Height - 1;
+ result = FocusedItem.Index + page_size - 1;
+ if (result >= Items.Count)
+ result = Items.Count - 1;
+ }
+ } else
+ result = last_index;
+ break;
+ case Keys.PageUp:
+ int first_index = FirstVisibleIndex;
+ if (Items [first_index].Bounds.Y < 0)
+ first_index++;
+ if (FocusedItem.Index == first_index) {
+ if (first_index > 0) {
+ int page_size = item_control.Height / items [0].Bounds.Height - 1;
+ result = first_index - page_size + 1;
+ if (result < 0)
+ result = 0;
+ }
+ } else
+ result = first_index;
+ break;
}
return result;
}
case Keys.Right:
if (col == (cols - 1))
return -1;
- while (item_matrix [row, col + 1] == null)
- row--;
+ while (item_matrix [row, col + 1] == null) {
+ row--;
+ if (row < 0)
+ return -1;
+ }
return item_matrix [row, col + 1].Index;
case Keys.Up:
case Keys.Down:
if (row == (rows - 1) || row == Items.Count - 1)
return -1;
- while (item_matrix [row + 1, col] == null)
- col--;
+ while (item_matrix [row + 1, col] == null) {
+ col--;
+ if (col < 0)
+ return -1;
+ }
return item_matrix [row + 1, col].Index;
default:
case Keys.Right:
case Keys.Up:
case Keys.Down:
+ case Keys.PageUp:
+ case Keys.PageDown:
SelectIndex (GetAdjustedIndex (key_data));
break;
ke.Handled = KeySearchString (ke);
}
+ private MouseEventArgs TranslateMouseEventArgs (MouseEventArgs args)
+ {
+ Point loc = PointToClient (Control.MousePosition);
+ return new MouseEventArgs (args.Button, args.Clicks, loc.X, loc.Y, args.Delta);
+ }
+
internal class ItemControl : Control {
ListView owner;
private void ItemsMouseDown (object sender, MouseEventArgs me)
{
- if (owner.items.Count == 0)
+ if (owner.items.Count == 0) {
+ owner.OnMouseDown (owner.TranslateMouseEventArgs (me));
return;
+ }
Point pt = new Point (me.X, me.Y);
foreach (ListViewItem item in owner.items) {
if (me.Clicks == 1 && item.CheckRectReal.Contains (pt)) {
checking = true;
- if (me.Clicks > 1)
- return;
ToggleCheckState (item);
+ owner.OnMouseDown (owner.TranslateMouseEventArgs (me));
return;
}
owner.OnSelectedIndexChanged (EventArgs.Empty);
}
}
+
+ owner.OnMouseDown (owner.TranslateMouseEventArgs (me));
}
private void ItemsMouseMove (object sender, MouseEventArgs me)
{
- if (PerformBoxSelection (new Point (me.X, me.Y)))
- return;
+ bool done = PerformBoxSelection (new Point (me.X, me.Y));
- if (owner.HoverSelection && hover_processed) {
+ if (!done && owner.HoverSelection && hover_processed) {
Point pt = PointToClient (Control.MousePosition);
ListViewItem item = owner.GetItemAt (pt.X, pt.Y);
- if (item == null || item.Selected)
- return;
-
- hover_processed = false;
- XplatUI.ResetMouseHover (Handle);
+ if (item != null && !item.Selected) {
+ hover_processed = false;
+ XplatUI.ResetMouseHover (Handle);
+ }
}
+
+ owner.OnMouseMove (owner.TranslateMouseEventArgs (me));
}
private void ItemsMouseHover (object sender, EventArgs e)
{
+ owner.OnMouseHover(e);
+
if (Capture || !owner.HoverSelection)
return;
private void ItemsMouseUp (object sender, MouseEventArgs me)
{
Capture = false;
- if (owner.Items.Count == 0)
+ if (owner.Items.Count == 0) {
+ owner.OnMouseUp (owner.TranslateMouseEventArgs (me));
return;
+ }
Point pt = new Point (me.X, me.Y);
prev_selection = null;
box_select_mode = BoxSelect.None;
checking = false;
+ owner.OnMouseUp (owner.TranslateMouseEventArgs (me));
}
internal void LabelEditFinished (object sender, EventArgs e)
ThemeEngine.Current.DrawListViewItems (pe.Graphics, pe.ClipRectangle, owner);
}
- internal override void OnGotFocusInternal (EventArgs e)
+ protected override void WndProc (ref Message m)
{
- owner.Focus ();
+ switch ((Msg)m.Msg) {
+ case Msg.WM_KILLFOCUS:
+ owner.Select (false, true);
+ break;
+ case Msg.WM_SETFOCUS:
+ owner.Select (false, true);
+ break;
+ default:
+ break;
+ }
+ base.WndProc (ref m);
}
}
// FIXME: TODO
}
+ bool refocusing = false;
+
protected override void WndProc (ref Message m)
{
+ switch ((Msg)m.Msg) {
+ case Msg.WM_KILLFOCUS:
+ Control receiver = Control.FromHandle (m.WParam);
+ if (receiver == item_control) {
+ has_focus = false;
+ refocusing = true;
+ return;
+ }
+ break;
+ case Msg.WM_SETFOCUS:
+ if (refocusing) {
+ has_focus = true;
+ refocusing = false;
+ return;
+ }
+ break;
+ default:
+ break;
+ }
base.WndProc (ref m);
}
#endregion // Protected Methods
}
}
+#if NET_2_0
+ public void AutoResizeColumn (int columnIndex, ColumnHeaderAutoResizeStyle headerAutoResize)
+ {
+ if (columnIndex < 0 || columnIndex >= columns.Count)
+ throw new ArgumentOutOfRangeException ("columnIndex");
+
+ columns [columnIndex].AutoResize (headerAutoResize);
+ }
+
+ public void AutoResizeColumns (ColumnHeaderAutoResizeStyle headerAutoResize)
+ {
+ BeginUpdate ();
+ foreach (ColumnHeader col in columns)
+ col.AutoResize (headerAutoResize);
+ EndUpdate ();
+ }
+#endif
+
public void BeginUpdate ()
{
// flag to avoid painting
if (view_rect.Contains (bounds))
return;
- if (bounds.Left < 0)
- h_scroll.Value += bounds.Left;
- else if (bounds.Right > view_rect.Right)
- h_scroll.Value += (bounds.Right - view_rect.Right);
+ if (View != View.Details) {
+ if (bounds.Left < 0)
+ h_scroll.Value += bounds.Left;
+ else if (bounds.Right > view_rect.Right)
+ h_scroll.Value += (bounds.Right - view_rect.Right);
+ }
if (bounds.Top < 0)
v_scroll.Value += bounds.Top;
else if (bounds.Bottom > view_rect.Bottom)
v_scroll.Value += (bounds.Bottom - view_rect.Bottom);
}
+
+#if NET_2_0
+ public ListViewItem FindItemWithText (string text)
+ {
+ if (items.Count == 0)
+ return null;
+
+ return FindItemWithText (text, true, 0, true);
+ }
+
+ public ListViewItem FindItemWithText (string text, bool includeSubItems, int startIndex)
+ {
+ return FindItemWithText (text, includeSubItems, startIndex, true);
+ }
+
+ public ListViewItem FindItemWithText (string text, bool includeSubItems, int startIndex, bool prefixSearch)
+ {
+ if (startIndex < 0 || startIndex >= items.Count)
+ throw new ArgumentOutOfRangeException ("startIndex");
+
+ if (text == null)
+ throw new ArgumentNullException ("text");
+
+ for (int i = startIndex; i < items.Count; i++) {
+ ListViewItem lvi = items [i];
+
+ if ((prefixSearch && lvi.Text.StartsWith (text, true, CultureInfo.CurrentCulture)) // prefix search
+ || String.Compare (lvi.Text, text, true) == 0) // match
+ return lvi;
+ }
+
+ if (includeSubItems) {
+ for (int i = startIndex; i < items.Count; i++) {
+ ListViewItem lvi = items [i];
+ foreach (ListViewItem.ListViewSubItem sub_item in lvi.SubItems)
+ if ((prefixSearch && sub_item.Text.StartsWith (text, true, CultureInfo.CurrentCulture))
+ || String.Compare (sub_item.Text, text, true) == 0)
+ return lvi;
+ }
+ }
+
+ return null;
+ }
+#endif
public ListViewItem GetItemAt (int x, int y)
{
if (owner.AllowColumnReorder) {
drag_x = me.X;
drag_column = (ColumnHeader) (clicked_column as ICloneable).Clone ();
- drag_column.column_rect = clicked_column.Rect;
+ drag_column.Rect = clicked_column.Rect;
drag_to_index = GetReorderedIndex (clicked_column);
}
- clicked_column.pressed = true;
+ clicked_column.Pressed = true;
Rectangle bounds = clicked_column.Rect;
bounds.X -= owner.h_marker;
Invalidate (bounds);
}
}
+ void StopResize ()
+ {
+ column_resize_active = false;
+ resize_column = null;
+ Capture = false;
+ Cursor = Cursors.Default;
+ }
+
private void HeaderMouseMove (object sender, MouseEventArgs me)
{
Point pt = new Point (me.X + owner.h_marker, me.Y);
if (column_resize_active) {
- resize_column.Width = pt.X - resize_column.X;
- if (resize_column.Width < 0)
- resize_column.Width = 0;
+ int width = pt.X - resize_column.X;
+ if (width < 0)
+ width = 0;
+
+ if (!owner.CanProceedWithResize (resize_column, width)){
+ StopResize ();
+ return;
+ }
+ resize_column.Width = width;
return;
}
if (owner.AllowColumnReorder) {
Rectangle r;
- r = drag_column.column_rect;
+ r = drag_column.Rect;
r.X = clicked_column.Rect.X + me.X - drag_x;
- drag_column.column_rect = r;
+ drag_column.Rect = r;
int x = me.X + owner.h_marker;
ColumnHeader over = ColumnAtX (x);
Invalidate ();
} else {
ColumnHeader over = ColumnAtX (me.X + owner.h_marker);
- bool pressed = clicked_column.pressed;
- clicked_column.pressed = over == clicked_column;
- if (clicked_column.pressed ^ pressed) {
+ bool pressed = clicked_column.Pressed;
+ clicked_column.Pressed = over == clicked_column;
+ if (clicked_column.Pressed ^ pressed) {
Rectangle bounds = clicked_column.Rect;
bounds.X -= owner.h_marker;
Invalidate (bounds);
Capture = false;
if (column_resize_active) {
- column_resize_active = false;
- resize_column = null;
- Cursor = Cursors.Default;
+ int column_idx = resize_column.Index;
+ StopResize ();
+ owner.RaiseColumnWidthChanged (column_idx);
return;
}
- if (clicked_column != null && clicked_column.pressed) {
- clicked_column.pressed = false;
+ if (clicked_column != null && clicked_column.Pressed) {
+ clicked_column.Pressed = false;
Rectangle bounds = clicked_column.Rect;
bounds.X -= owner.h_marker;
Invalidate (bounds);
}
}
+#if NET_2_0
+ public virtual ListViewItem this [string key] {
+ get {
+ int idx = IndexOfKey (key);
+ return idx == -1 ? null : (ListViewItem) List [idx];
+ }
+ }
+#endif
+
bool ICollection.IsSynchronized {
get { return false; }
}
return List.Contains (item);
}
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
+ {
+ return IndexOfKey (key) != -1;
+ }
+#endif
+
public void CopyTo (Array dest, int index)
{
if (!owner.CheckBoxes)
return -1;
return List.IndexOf (item);
}
+
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ if (key == null || key.Length == 0)
+ return -1;
+
+ ArrayList checked_items = List;
+ for (int i = 0; i < checked_items.Count; i++) {
+ ListViewItem item = (ListViewItem) checked_items [i];
+ if (String.Compare (key, item.Name, true) == 0)
+ return i;
+ }
+
+ return -1;
+ }
+#endif
#endregion // Public Methods
internal ArrayList List {
}
}
+#if NET_2_0
+ public virtual ColumnHeader this [string key] {
+ get {
+ int idx = IndexOfKey (key);
+ if (idx == -1)
+ return null;
+
+ return (ColumnHeader) list [idx];
+ }
+ }
+#endif
+
bool ICollection.IsSynchronized {
get { return true; }
}
public virtual int Add (ColumnHeader value)
{
int idx;
- value.owner = this.owner;
+ value.SetListView (this.owner);
idx = list.Add (value);
if (owner.IsHandleCreated) {
owner.Redraw (true);
return colHeader;
}
+#if NET_2_0
+ public virtual ColumnHeader Add (string text)
+ {
+ return Add (String.Empty, text);
+ }
+
+ public virtual ColumnHeader Add (string text, int iwidth)
+ {
+ return Add (String.Empty, text, iwidth);
+ }
+
+ public virtual ColumnHeader Add (string key, string text)
+ {
+ ColumnHeader colHeader = new ColumnHeader ();
+ colHeader.Name = key;
+ colHeader.Text = text;
+ Add (colHeader);
+ return colHeader;
+ }
+
+ public virtual ColumnHeader Add (string key, string text, int iwidth)
+ {
+ return Add (key, text, iwidth, HorizontalAlignment.Left, -1);
+ }
+
+ public virtual ColumnHeader Add (string key, string text, int iwidth, HorizontalAlignment textAlign, int imageIndex)
+ {
+ ColumnHeader colHeader = new ColumnHeader (key, text, iwidth, textAlign);
+ colHeader.ImageIndex = imageIndex;
+ Add (colHeader);
+ return colHeader;
+ }
+
+ public virtual ColumnHeader Add (string key, string text, int iwidth, HorizontalAlignment textAlign, string imageKey)
+ {
+ ColumnHeader colHeader = new ColumnHeader (key, text, iwidth, textAlign);
+ colHeader.ImageKey = imageKey;
+ Add (colHeader);
+ return colHeader;
+ }
+#endif
+
public virtual void AddRange (ColumnHeader [] values)
{
foreach (ColumnHeader colHeader in values) {
- colHeader.owner = this.owner;
+ colHeader.SetListView (this.owner);
Add (colHeader);
}
return list.Contains (value);
}
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
+ {
+ return IndexOfKey (key) != -1;
+ }
+#endif
+
public IEnumerator GetEnumerator ()
{
return list.GetEnumerator ();
return list.IndexOf (value);
}
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ if (key == null || key.Length == 0)
+ return -1;
+
+ for (int i = 0; i < list.Count; i++) {
+ ColumnHeader col = (ColumnHeader) list [i];
+ if (String.Compare (key, col.Name, true) == 0)
+ return i;
+ }
+
+ return -1;
+ }
+#endif
+
public void Insert (int index, ColumnHeader value)
{
// LAMESPEC: MSDOCS say greater than or equal to the value of the Count property
if (index < 0 || index > list.Count)
throw new ArgumentOutOfRangeException ("index");
- value.owner = this.owner;
+ value.SetListView (owner);
list.Insert (index, value);
owner.Redraw (true);
}
+#if NET_2_0
+ public void Insert (int index, string text)
+ {
+ Insert (index, String.Empty, text);
+ }
+
+ public void Insert (int index, string text, int width)
+ {
+ Insert (index, String.Empty, text, width);
+ }
+
+ public void Insert (int index, string key, string text)
+ {
+ ColumnHeader colHeader = new ColumnHeader ();
+ colHeader.Name = key;
+ colHeader.Text = text;
+ Insert (index, colHeader);
+ }
+
+ public void Insert (int index, string key, string text, int width)
+ {
+ ColumnHeader colHeader = new ColumnHeader (key, text, width, HorizontalAlignment.Left);
+ Insert (index, colHeader);
+ }
+
+ public void Insert (int index, string key, string text, int width, HorizontalAlignment textAlign, int imageIndex)
+ {
+ ColumnHeader colHeader = new ColumnHeader (key, text, width, textAlign);
+ colHeader.ImageIndex = imageIndex;
+ Insert (index, colHeader);
+ }
+
+ public void Insert (int index, string key, string text, int width, HorizontalAlignment textAlign, string imageKey)
+ {
+ ColumnHeader colHeader = new ColumnHeader (key, text, width, textAlign);
+ colHeader.ImageKey = imageKey;
+ Insert (index, colHeader);
+ }
+#endif
+
public void Insert (int index, string str, int width, HorizontalAlignment textAlign)
{
ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
owner.Redraw (true);
}
+#if NET_2_0
+ public virtual void RemoveByKey (string key)
+ {
+ int idx = IndexOfKey (key);
+ if (idx != -1)
+ RemoveAt (idx);
+ }
+#endif
+
public virtual void RemoveAt (int index)
{
if (index < 0 || index >= list.Count)
if (list.Contains (value))
throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
+ if (value.ListView != null && value.ListView != owner)
+ throw new ArgumentException ("Cannot add or insert the item '" + value.Text + "' in more than one place. You must first remove it from its current location or clone it.", "value");
+
value.Owner = owner;
list [displayIndex] = value;
OnChange ();
}
}
+#if NET_2_0
+ public virtual ListViewItem this [string key] {
+ get {
+ int idx = IndexOfKey (key);
+ if (idx == -1)
+ return null;
+
+ return (ListViewItem) list [idx];
+ }
+ }
+#endif
+
bool ICollection.IsSynchronized {
get { return true; }
}
if (list.Contains (value))
throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
+ if (value.ListView != null && value.ListView != owner)
+ throw new ArgumentException ("Cannot add or insert the item '" + value.Text + "' in more than one place. You must first remove it from its current location or clone it.", "value");
+
value.Owner = owner;
list.Add (value);
- owner.Sort (false);
- OnChange ();
- owner.Redraw (true);
+ if (this.owner != null)
+ {
+ owner.Sort (false);
+ OnChange ();
+ owner.Redraw (true);
+ }
+
return value;
}
return this.Add (item);
}
+#if NET_2_0
+ public virtual ListViewItem Add (string text, string imageKey)
+ {
+ ListViewItem item = new ListViewItem (text, imageKey);
+ return this.Add (item);
+ }
+
+ public virtual ListViewItem Add (string key, string text, int imageIndex)
+ {
+ ListViewItem item = new ListViewItem (text, imageIndex);
+ item.Name = key;
+ return this.Add (item);
+ }
+
+ public virtual ListViewItem Add (string key, string text, string imageKey)
+ {
+ ListViewItem item = new ListViewItem (text, imageKey);
+ item.Name = key;
+ return this.Add (item);
+ }
+#endif
+
public void AddRange (ListViewItem [] values)
{
- list.Clear ();
+ if (values == null)
+ throw new ArgumentNullException ("Argument cannot be null!", "values");
foreach (ListViewItem item in values) {
- item.Owner = owner;
- list.Add (item);
+ this.Add (item);
}
+ }
- owner.Sort (false);
- OnChange ();
- owner.Redraw (true);
+#if NET_2_0
+ public void AddRange (ListViewItemCollection items)
+ {
+ if (items == null)
+ throw new ArgumentNullException ("Argument cannot be null!", "items");
+
+ ListViewItem[] itemArray = new ListViewItem[items.Count];
+ items.CopyTo (itemArray,0);
+ this.AddRange (itemArray);
}
+#endif
public virtual void Clear ()
{
return list.Contains (item);
}
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
+ {
+ return IndexOfKey (key) != -1;
+ }
+#endif
+
public void CopyTo (Array dest, int index)
{
list.CopyTo (dest, index);
}
+#if NET_2_0
+ public ListViewItem [] Find (string key, bool searchAllSubitems)
+ {
+ if (key == null)
+ return new ListViewItem [0];
+
+ List<ListViewItem> temp_list = new List<ListViewItem> ();
+
+ for (int i = 0; i < list.Count; i++) {
+ ListViewItem lvi = (ListViewItem) list [i];
+ if (String.Compare (key, lvi.Name, true) == 0)
+ temp_list.Add (lvi);
+ }
+
+ ListViewItem [] retval = new ListViewItem [temp_list.Count];
+ temp_list.CopyTo (retval);
+
+ return retval;
+ }
+#endif
+
public IEnumerator GetEnumerator ()
{
return list.GetEnumerator ();
li = (ListViewItem) item;
if (list.Contains (li))
throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
+
+ if (li.ListView != null && li.ListView != owner)
+ throw new ArgumentException ("Cannot add or insert the item '" + li.Text + "' in more than one place. You must first remove it from its current location or clone it.", "item");
}
else
li = new ListViewItem (item.ToString ());
return list.IndexOf (item);
}
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ if (key == null || key.Length == 0)
+ return -1;
+
+ for (int i = 0; i < list.Count; i++) {
+ ListViewItem lvi = (ListViewItem) list [i];
+ if (String.Compare (key, lvi.Name, true) == 0)
+ return i;
+ }
+
+ return -1;
+ }
+#endif
+
public ListViewItem Insert (int index, ListViewItem item)
{
if (index < 0 || index > list.Count)
if (list.Contains (item))
throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
+ if (item.ListView != null && item.ListView != owner)
+ throw new ArgumentException ("Cannot add or insert the item '" + item.Text + "' in more than one place. You must first remove it from its current location or clone it.", "item");
+
item.Owner = owner;
list.Insert (index, item);
OnChange ();
return this.Insert (index, new ListViewItem (text, imageIndex));
}
+#if NET_2_0
+ public ListViewItem Insert (int index, string key, string text, int imageIndex)
+ {
+ ListViewItem lvi = new ListViewItem (text, imageIndex);
+ lvi.Name = key;
+ return Insert (index, lvi);
+ }
+#endif
+
public virtual void Remove (ListViewItem item)
{
if (!list.Contains (item))
if (selection_changed)
owner.OnSelectedIndexChanged (EventArgs.Empty);
}
+
+#if NET_2_0
+ public virtual void RemoveByKey (string key)
+ {
+ int idx = IndexOfKey (key);
+ if (idx != -1)
+ RemoveAt (idx);
+ }
+#endif
+
#endregion // Public Methods
internal event CollectionChangedHandler Changed;
}
public bool IsReadOnly {
- get { return true; }
+ get {
+#if NET_2_0
+ return false;
+#else
+ return true;
+#endif
+ }
}
public int this [int index] {
}
bool IList.IsFixedSize {
- get { return true; }
+ get {
+#if NET_2_0
+ return false;
+#else
+ return true;
+#endif
+ }
}
object IList.this [int index] {
#endregion // Public Properties
#region Public Methods
+#if NET_2_0
+ public int Add (int itemIndex)
+ {
+ if (itemIndex < 0 || itemIndex >= owner.Items.Count)
+ throw new ArgumentOutOfRangeException ("index");
+
+ owner.Items [itemIndex].Selected = true;
+ if (!owner.IsHandleCreated)
+ return 0;
+
+ return owner.SelectedItems.Count;
+ }
+
+ public void Clear ()
+ {
+ owner.SelectedItems.Clear ();
+ }
+#endif
public bool Contains (int selectedIndex)
{
int [] indices = GetIndices ();
}
return -1;
}
+
+#if NET_2_0
+ public void Remove (int itemIndex)
+ {
+ if (itemIndex < 0 || itemIndex >= owner.Items.Count)
+ throw new ArgumentOutOfRangeException ("itemIndex");
+
+ owner.Items [itemIndex].Selected = false;
+ }
+#endif
#endregion // Public Methods
private int [] GetIndices ()
}
}
+#if NET_2_0
+ public virtual ListViewItem this [string key] {
+ get {
+ int idx = IndexOfKey (key);
+ if (idx == -1)
+ return null;
+
+ return (ListViewItem) List [idx];
+ }
+ }
+#endif
+
bool ICollection.IsSynchronized {
get { return false; }
}
return List.Contains (item);
}
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
+ {
+ return IndexOfKey (key) != -1;
+ }
+#endif
+
public void CopyTo (Array dest, int index)
{
if (!owner.IsHandleCreated)
return -1;
return List.IndexOf (item);
}
+
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ if (!owner.IsHandleCreated || key == null || key.Length == 0)
+ return -1;
+
+ ArrayList selected_items = List;
+ for (int i = 0; i < selected_items.Count; i++) {
+ ListViewItem item = (ListViewItem) selected_items [i];
+ if (String.Compare (item.Name, key, true) == 0)
+ return i;
+ }
+
+ return -1;
+ }
+#endif
#endregion // Public Methods
internal ArrayList List {
internal delegate void CollectionChangedHandler ();
#endregion // Subclasses
+#if NET_2_0
+ protected override void OnResize (EventArgs e)
+ {
+ base.OnResize (e);
+ }
+
+ protected override void OnMouseLeave (EventArgs e)
+ {
+ base.OnMouseLeave (e);
+ }
+
+ //
+ // ColumnReorder event
+ //
+ static object ColumnReorderedEvent = new object ();
+ public event ColumnReorderedEventHandler ColumnReordered {
+ add { Events.AddHandler (ColumnReorderedEvent, value); }
+ remove { Events.RemoveHandler (ColumnReorderedEvent, value); }
+ }
+
+ protected virtual void OnColumnReordered (ColumnReorderedEventArgs e)
+ {
+ ColumnReorderedEventHandler creh = (ColumnReorderedEventHandler) (Events [ColumnReorderedEvent]);
+
+ if (creh != null)
+ creh (this, e);
+ }
+
+ //
+ // ColumnWidthChanged
+ //
+ static object ColumnWidthChangedEvent = new object ();
+ public event ColumnWidthChangedEventHandler ColumnWidthChanged {
+ add { Events.AddHandler (ColumnWidthChangedEvent, value); }
+ remove { Events.RemoveHandler (ColumnWidthChangedEvent, value); }
+ }
+
+ protected virtual void OnColumnWidthChanged (ColumnWidthChangedEventArgs e)
+ {
+ ColumnWidthChangedEventHandler eh = (ColumnWidthChangedEventHandler) (Events[ColumnWidthChangedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+
+ void RaiseColumnWidthChanged (int resize_column)
+ {
+ ColumnWidthChangedEventArgs n = new ColumnWidthChangedEventArgs (resize_column);
+
+ OnColumnWidthChanged (n);
+ }
+
+ //
+ // ColumnWidthChanging
+ //
+ static object ColumnWidthChangingEvent = new object ();
+ public event ColumnWidthChangingEventHandler ColumnWidthChanging {
+ add { Events.AddHandler (ColumnWidthChangingEvent, value); }
+ remove { Events.RemoveHandler (ColumnWidthChangingEvent, value); }
+ }
+
+ protected virtual void OnColumnWidthChanging (ColumnWidthChangingEventArgs e)
+ {
+ ColumnWidthChangingEventHandler cwceh = (ColumnWidthChangingEventHandler) (Events[ColumnWidthChangingEvent]);
+ if (cwceh != null)
+ cwceh (this, e);
+ }
+
+ //
+ // 2.0 profile based implementation
+ //
+ bool CanProceedWithResize (ColumnHeader col, int width)
+ {
+ ColumnWidthChangingEventHandler cwceh = (ColumnWidthChangingEventHandler) (Events[ColumnWidthChangingEvent]);
+ if (cwceh == null)
+ return true;
+
+ ColumnWidthChangingEventArgs changing = new ColumnWidthChangingEventArgs (col.Index, width);
+ cwceh (this, changing);
+ return !changing.Cancel;
+ }
+#else
+ //
+ // 1.0 profile based implementation
+ //
+ bool CanProceedWithResize (ColumnHeader col, int width)
+ {
+ return true;
+ }
+
+ void RaiseColumnWidthChanged (int resize_column)
+ {
+ }
+#endif
}
}