// 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 allow_column_reorder = false;
private bool auto_arrange = true;
private bool check_boxes = false;
- private CheckedIndexCollection checked_indices;
- private CheckedListViewItemCollection checked_items;
- private ColumnHeaderCollection columns;
+ private readonly CheckedIndexCollection checked_indices;
+ private readonly CheckedListViewItemCollection checked_items;
+ private readonly ColumnHeaderCollection columns;
internal ListViewItem focused_item;
private bool full_row_select = false;
private bool grid_lines = false;
private ColumnHeaderStyle header_style = ColumnHeaderStyle.Clickable;
private bool hide_selection = true;
private bool hover_selection = false;
- private IComparer item_sorter = new ItemComparer ();
- private ListViewItemCollection items;
+ 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 bool scrollable = true;
- private SelectedIndexCollection selected_indices;
- private SelectedListViewItemCollection selected_items;
+ private readonly SelectedIndexCollection selected_indices;
+ private readonly SelectedListViewItemCollection selected_items;
private SortOrder sort_order = SortOrder.None;
private ImageList state_image_list;
private bool updating = false;
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;
internal Size text_size = Size.Empty;
#region Events
- public event LabelEditEventHandler AfterLabelEdit;
+ static object AfterLabelEditEvent = new object ();
+ static object BeforeLabelEditEvent = new object ();
+ static object ColumnClickEvent = new object ();
+ static object ItemActivateEvent = new object ();
+ static object ItemCheckEvent = new object ();
+ static object ItemDragEvent = new object ();
+ static object SelectedIndexChangedEvent = new object ();
+
+ public event LabelEditEventHandler AfterLabelEdit {
+ add { Events.AddHandler (AfterLabelEditEvent, value); }
+ remove { Events.RemoveHandler (AfterLabelEditEvent, value); }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
remove { base.BackgroundImageChanged -= value; }
}
- public event LabelEditEventHandler BeforeLabelEdit;
- public event ColumnClickEventHandler ColumnClick;
- public event EventHandler ItemActivate;
- public event ItemCheckEventHandler ItemCheck;
- public event ItemDragEventHandler ItemDrag;
+ public event LabelEditEventHandler BeforeLabelEdit {
+ add { Events.AddHandler (BeforeLabelEditEvent, value); }
+ remove { Events.RemoveHandler (BeforeLabelEditEvent, value); }
+ }
+
+ public event ColumnClickEventHandler ColumnClick {
+ add { Events.AddHandler (ColumnClickEvent, value); }
+ remove { Events.RemoveHandler (ColumnClickEvent, value); }
+ }
+
+ public event EventHandler ItemActivate {
+ add { Events.AddHandler (ItemActivateEvent, value); }
+ remove { Events.RemoveHandler (ItemActivateEvent, value); }
+ }
+
+ public event ItemCheckEventHandler ItemCheck {
+ add { Events.AddHandler (ItemCheckEvent, value); }
+ remove { Events.RemoveHandler (ItemCheckEvent, value); }
+ }
+
+ public event ItemDragEventHandler ItemDrag {
+ add { Events.AddHandler (ItemDragEvent, value); }
+ remove { Events.RemoveHandler (ItemDragEvent, value); }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
remove { base.Paint -= value; }
}
- public event EventHandler SelectedIndexChanged;
+ public event EventHandler SelectedIndexChanged {
+ add { Events.AddHandler (SelectedIndexChangedEvent, value); }
+ remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public ListView ()
{
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);
foreground_color = SystemColors.WindowText;
- items = new ListViewItemCollection (this);
selected_indices = new SelectedIndexCollection (this);
selected_items = new SelectedListViewItemCollection (this);
item_control = new ItemControl (this);
Controls.AddImplicit (item_control);
- h_scroll = new HScrollBar ();
+ h_scroll = new ImplicitHScrollBar ();
Controls.AddImplicit (this.h_scroll);
- v_scroll = new VScrollBar ();
+ v_scroll = new ImplicitVScrollBar ();
Controls.AddImplicit (this.v_scroll);
h_marker = v_marker = 0;
LostFocus += new EventHandler (FocusChanged);
MouseWheel += new MouseEventHandler(ListView_MouseWheel);
- this.SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick, false);
+ this.SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick
+#if NET_2_0
+ | ControlStyles.UseTextForAccessibility
+#endif
+ , false);
}
#endregion // Public Constructors
}
}
- bool multiselecting;
-
- bool CanMultiselect {
- get {
- if (multiselecting)
- return true;
- else if (multiselect && (XplatUI.State.ModifierKeys & (Keys.Control | Keys.Shift)) != 0)
- return true;
- else
- return false;
- }
- }
-
#endregion // Private Internal Properties
#region Protected Properties
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override Image BackgroundImage {
- get { return background_image; }
- set {
- if (value == background_image)
- return;
-
- background_image = value;
- OnBackgroundImageChanged (EventArgs.Empty);
- }
+ get { return base.BackgroundImage; }
+ set { base.BackgroundImage = value; }
}
[DefaultValue (BorderStyle.Fixed3D)]
get { return check_boxes; }
set {
if (check_boxes != value) {
+#if NET_2_0
+ if (value && View == View.Tile)
+ throw new NotSupportedException ("CheckBoxes are not"
+ + " supported in Tile view. Choose a different"
+ + " view or set CheckBoxes to false.");
+#endif
+
check_boxes = value;
this.Redraw (true);
}
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public IComparer ListViewItemSorter {
- get { return item_sorter; }
- set { item_sorter = value; }
+ get {
+ if (View != View.SmallIcon && View != View.LargeIcon && item_sorter is ItemComparer)
+ return null;
+ return item_sorter;
+ }
+ set {
+ if (item_sorter != value) {
+ item_sorter = value;
+ Sort ();
+ }
+ }
}
[DefaultValue (true)]
}
#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)]
+ public ListViewGroupCollection Groups {
+ get { return groups; }
}
#endif
public SortOrder Sorting {
get { return sort_order; }
set {
- if (value != SortOrder.Ascending && value != SortOrder.Descending &&
- value != SortOrder.None) {
- throw new InvalidEnumArgumentException (string.Format
- ("Enum argument value '{0}' is not valid for Sorting", value));
+ if (!Enum.IsDefined (typeof (SortOrder), value)) {
+ throw new InvalidEnumArgumentException ("value", (int) value,
+ typeof (SortOrder));
}
- if (sort_order != value) {
- sort_order = value;
+ if (sort_order == value)
+ return;
+
+ sort_order = value;
+
+ if (value == SortOrder.None) {
+ if (item_sorter != null) {
+ // ListViewItemSorter should never be reset for SmallIcon
+ // and LargeIcon view
+ if (View != View.SmallIcon && View != View.LargeIcon)
+#if NET_2_0
+ item_sorter = null;
+#else
+ // in .NET 1.1, only internal IComparer would be
+ // set to null
+ if (item_sorter is ItemComparer)
+ item_sorter = null;
+#endif
+ }
this.Redraw (false);
+ } else {
+ if (item_sorter == null)
+ item_sorter = new ItemComparer (value);
+ if (item_sorter is ItemComparer) {
+#if NET_2_0
+ item_sorter = new ItemComparer (value);
+#else
+ // in .NET 1.1, the sort order is not updated for
+ // SmallIcon and LargeIcon views if no custom IComparer
+ // is set
+ if (View != View.SmallIcon && View != View.LargeIcon)
+ item_sorter = new ItemComparer (value);
+#endif
+ }
+ Sort ();
}
}
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override string Text {
- get { return text; }
+ get { return base.Text; }
set {
- if (value == text)
+ if (value == base.Text)
return;
- text = value;
+ base.Text = value;
this.Redraw (true);
+ }
+ }
+
+#if NET_2_0
+ public Size TileSize {
+ get {
+ return tile_size;
+ }
+ set {
+ if (value.Width <= 0 || value.Height <= 0)
+ throw new ArgumentOutOfRangeException ("value");
- OnTextChanged (EventArgs.Empty);
+ tile_size = value;
+ Redraw (true);
}
}
+#endif
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public View View {
get { return view; }
set {
- if (value != View.Details && value != View.LargeIcon &&
- value != View.List && value != View.SmallIcon ) {
- throw new InvalidEnumArgumentException (string.Format
- ("Enum argument value '{0}' is not valid for View", value));
- }
-
+ if (!Enum.IsDefined (typeof (View), value))
+ throw new InvalidEnumArgumentException ("value", (int) value,
+ typeof (View));
+
if (view != value) {
+#if NET_2_0
+ if (CheckBoxes && value == View.Tile)
+ throw new NotSupportedException ("CheckBoxes are not"
+ + " supported in Tile view. Choose a different"
+ + " view or set CheckBoxes to false.");
+#endif
+
h_scroll.Value = v_scroll.Value = 0;
view = value;
Redraw (true);
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;
}
}
}
}
+ internal void OnSelectedIndexChanged ()
+ {
+ if (IsHandleCreated)
+ OnSelectedIndexChanged (EventArgs.Empty);
+ }
+
internal int TotalWidth {
get { return Math.Max (this.Width, this.layout_wd); }
}
Refresh ();
}
+ const int text_padding = 5;
+
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);
return ret_size;
}
+ const int max_wrap_padding = 38;
+
// Sets the size of the biggest item text as per the view
private void CalcTextSize ()
{
Size temp = Size.Empty;
if (this.check_boxes)
temp.Width += 2 * this.CheckBoxSize.Width;
- if (large_image_list != null)
- temp.Width += large_image_list.ImageSize.Width;
- if (temp.Width == 0)
- temp.Width = 43;
+ int icon_w = LargeImageList == null ? 12 : LargeImageList.ImageSize.Width;
+ temp.Width += icon_w + max_wrap_padding;
// wrapping is done for two lines only
if (text_size.Width > temp.Width) {
text_size.Width = temp.Width;
item_control.Height = ClientRectangle.Height - header_control.Height;
- if (h_scroll.Visible) {
+ if (h_scroll.is_visible) {
h_scroll.Location = new Point (client_area.X, client_area.Bottom - h_scroll.Height);
h_scroll.Minimum = 0;
item_control.Height -= h_scroll.Height;
}
- if (header_control.Visible)
+ if (header_control.is_visible)
header_control.Width = ClientRectangle.Width;
item_control.Width = ClientRectangle.Width;
- if (v_scroll.Visible) {
+ if (v_scroll.is_visible) {
v_scroll.Location = new Point (client_area.Right - v_scroll.Width, client_area.Y);
v_scroll.Minimum = 0;
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 ();
}
- internal void UpdateSelection (ListViewItem item)
- {
- if (item.Selected) {
-
- if (!CanMultiselect && SelectedItems.Count > 0) {
- SelectedItems.Clear ();
- SelectedIndices.list.Clear ();
- }
-
- if (!SelectedItems.Contains (item)) {
- SelectedItems.list.Add (item);
- SelectedIndices.list.Add (item.Index);
- }
- } else {
- SelectedItems.list.Remove (item);
- SelectedIndices.list.Remove (item.Index);
- }
- }
-
private bool KeySearchString (KeyEventArgs ke)
{
int current_tickcnt = Environment.TickCount;
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:
private bool SelectItems (ArrayList sel_items)
{
bool changed = false;
- multiselecting = true;
- ArrayList curr_items = (ArrayList) SelectedItems.list.Clone ();
+ ArrayList curr_items = SelectedItems.List;
foreach (ListViewItem item in curr_items)
if (!sel_items.Contains (item)) {
item.Selected = false;
item.Selected = true;
changed = true;
}
- multiselecting = false;
return changed;
}
}
if (SelectItems (list))
OnSelectedIndexChanged (EventArgs.Empty);
- } else if (!ctrl_pressed) {
+ } else if (ctrl_pressed) {
+ item.Selected = !item.Selected;
+ selection_start = item;
+ OnSelectedIndexChanged (EventArgs.Empty);
+ } else {
SelectedItems.Clear ();
- SelectedIndices.list.Clear ();
item.Selected = true;
selection_start = item;
OnSelectedIndexChanged (EventArgs.Empty);
}
}
- private void ListView_KeyDown (object sender, KeyEventArgs ke)
- {
- if (ke.Handled || Items.Count == 0 || !item_control.Visible)
- return;
+ internal override bool InternalPreProcessMessage (ref Message msg)
+ {
+ if (msg.Msg == (int)Msg.WM_KEYDOWN) {
+ Keys key_data = (Keys)msg.WParam.ToInt32();
+ if (HandleNavKeys (key_data))
+ return true;
+ }
+ return base.InternalPreProcessMessage (ref msg);
+ }
- int index = -1;
- ke.Handled = true;
+ bool HandleNavKeys (Keys key_data)
+ {
+ if (Items.Count == 0 || !item_control.Visible)
+ return false;
if (FocusedItem == null)
SetFocusedItem (Items [0]);
- switch (ke.KeyCode) {
-
+ switch (key_data) {
case Keys.End:
- index = Items.Count - 1;
+ SelectIndex (Items.Count - 1);
break;
case Keys.Home:
- index = 0;
+ SelectIndex (0);
break;
case Keys.Left:
case Keys.Right:
case Keys.Up:
case Keys.Down:
- index = GetAdjustedIndex (ke.KeyCode);
+ case Keys.PageUp:
+ case Keys.PageDown:
+ SelectIndex (GetAdjustedIndex (key_data));
break;
default:
- ke.Handled = KeySearchString (ke);
- return;
+ return false;
}
-
+
+ return true;
+ }
+
+ void SelectIndex (int index)
+ {
if (index == -1)
return;
EnsureVisible (index);
}
-
+ private void ListView_KeyDown (object sender, KeyEventArgs ke)
+ {
+ if (ke.Handled || Items.Count == 0 || !item_control.Visible)
+ return;
+
+ 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;
ListViewItem last_clicked_item;
bool hover_processed = false;
bool checking = false;
+
+ ListViewLabelEditTextBox edit_text_box;
+ internal ListViewItem edit_item;
+ LabelEditEventArgs edit_args;
public ItemControl (ListView owner)
{
void ItemsDoubleClick (object sender, EventArgs e)
{
- if (owner.activation == ItemActivation.Standard && owner.ItemActivate != null)
- owner.ItemActivate (this, e);
+ if (owner.activation == ItemActivation.Standard)
+ owner.OnItemActivate (EventArgs.Empty);
}
enum BoxSelect {
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;
}
if (clicked_item != null) {
owner.SetFocusedItem (clicked_item);
bool changed = !clicked_item.Selected;
- if (owner.MultiSelect && (XplatUI.State.ModifierKeys & Keys.Control) == 0)
+ if (owner.MultiSelect)
owner.UpdateMultiSelection (clicked_item.Index);
else
clicked_item.Selected = true;
owner.OnDoubleClick (EventArgs.Empty);
if (owner.CheckBoxes)
ToggleCheckState (clicked_item);
- } else if (me.Clicks == 1)
+ } else if (me.Clicks == 1) {
owner.OnClick (EventArgs.Empty);
+ if (owner.LabelEdit && !changed)
+ BeginEdit (clicked_item); // this is probably not the correct place to execute BeginEdit
+ }
} else {
if (owner.MultiSelect) {
Keys mods = XplatUI.State.ModifierKeys;
else
box_select_mode = BoxSelect.Normal;
box_select_start = pt;
- prev_selection = (ArrayList) owner.SelectedItems.list.Clone ();
- } else if (owner.selected_indices.Count > 0) {
+ prev_selection = owner.SelectedItems.List;
+ } else if (owner.SelectedItems.Count > 0) {
owner.SelectedItems.Clear ();
- owner.SelectedIndices.list.Clear ();
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);
} else if (!checking && owner.SelectedItems.Count > 0 && BoxSelectRectangle.Size.IsEmpty) {
// Need this to clean up background clicks
owner.SelectedItems.Clear ();
- owner.SelectedIndices.list.Clear ();
owner.OnSelectedIndexChanged (EventArgs.Empty);
}
prev_selection = null;
box_select_mode = BoxSelect.None;
checking = false;
+ owner.OnMouseUp (owner.TranslateMouseEventArgs (me));
+ }
+
+ internal void LabelEditFinished (object sender, EventArgs e)
+ {
+ EndEdit (edit_item);
+ }
+
+ internal void BeginEdit (ListViewItem item)
+ {
+ if (edit_item != null)
+ EndEdit (edit_item);
+
+ if (edit_text_box == null) {
+ edit_text_box = new ListViewLabelEditTextBox ();
+ edit_text_box.BorderStyle = BorderStyle.FixedSingle;
+ edit_text_box.EditingFinished += new EventHandler (LabelEditFinished);
+ edit_text_box.Visible = false;
+ Controls.Add (edit_text_box);
+ }
+
+ item.EnsureVisible();
+
+ edit_text_box.Reset ();
+
+ switch (owner.view) {
+ case View.List:
+ case View.SmallIcon:
+ case View.Details:
+ edit_text_box.TextAlign = HorizontalAlignment.Left;
+ edit_text_box.Bounds = item.GetBounds (ItemBoundsPortion.Label);
+ SizeF sizef = DeviceContext.MeasureString (item.Text, item.Font);
+ edit_text_box.Width = (int)sizef.Width + 4;
+ edit_text_box.MaxWidth = owner.ClientRectangle.Width - edit_text_box.Bounds.X;
+ edit_text_box.WordWrap = false;
+ edit_text_box.Multiline = false;
+ break;
+ case View.LargeIcon:
+ edit_text_box.TextAlign = HorizontalAlignment.Center;
+ edit_text_box.Bounds = item.GetBounds (ItemBoundsPortion.Label);
+ sizef = DeviceContext.MeasureString (item.Text, item.Font);
+ edit_text_box.Width = (int)sizef.Width + 4;
+ edit_text_box.MaxWidth = item.GetBounds(ItemBoundsPortion.Entire).Width;
+ edit_text_box.MaxHeight = owner.ClientRectangle.Height - edit_text_box.Bounds.Y;
+ edit_text_box.WordWrap = true;
+ edit_text_box.Multiline = true;
+ break;
+ }
+
+ edit_text_box.Text = item.Text;
+ edit_text_box.Font = item.Font;
+ edit_text_box.Visible = true;
+ edit_text_box.Focus ();
+ edit_text_box.SelectAll ();
+
+ edit_args = new LabelEditEventArgs (owner.Items.IndexOf(edit_item));
+ owner.OnBeforeLabelEdit (edit_args);
+
+ if (edit_args.CancelEdit)
+ EndEdit (item);
+
+ edit_item = item;
+ }
+
+ internal void EndEdit (ListViewItem item)
+ {
+ if (edit_text_box != null && edit_text_box.Visible) {
+ edit_text_box.Visible = false;
+ }
+
+ if (edit_item != null && edit_item == item) {
+ owner.OnAfterLabelEdit (edit_args);
+
+ if (!edit_args.CancelEdit) {
+ if (edit_args.Label != null)
+ edit_item.Text = edit_args.Label;
+ else
+ edit_item.Text = edit_text_box.Text;
+ }
+
+ }
+
+
+ edit_item = null;
}
internal override void OnPaintInternal (PaintEventArgs pe)
internal override void OnGotFocusInternal (EventArgs e)
{
- owner.Focus ();
+ owner.Select (false, true);
}
- }
-
- internal override void OnPaintInternal (PaintEventArgs pe)
- {
- if (updating)
- return;
-
- CalculateScrollBars ();
- }
-
- void FocusChanged (object o, EventArgs args)
- {
- if (Items.Count == 0)
- return;
-
- if (FocusedItem == null)
- SetFocusedItem (Items [0]);
-
- item_control.Invalidate (FocusedItem.Bounds);
- }
-
- private void ListView_MouseWheel (object sender, MouseEventArgs me)
- {
- if (Items.Count == 0)
- return;
-
- int lines = me.Delta / 120;
-
- if (lines == 0)
- return;
- switch (View) {
- case View.Details:
- case View.SmallIcon:
- Scroll (v_scroll, -Items [0].Bounds.Height * SystemInformation.MouseWheelScrollLines * lines);
- break;
- case View.LargeIcon:
- Scroll (v_scroll, -(Items [0].Bounds.Height + ThemeEngine.Current.ListViewVerticalSpacing) * lines);
- break;
- case View.List:
- Scroll (h_scroll, -Items [0].Bounds.Width * lines);
- break;
+ internal override void OnLostFocusInternal (EventArgs e)
+ {
+ owner.Select (false, true);
}
}
-
- private void ListView_SizeChanged (object sender, EventArgs e)
- {
- CalculateListView (alignment);
- }
- private void SetFocusedItem (ListViewItem item)
+ internal class ListViewLabelEditTextBox : TextBox
{
- if (focused_item != null)
- focused_item.Focused = false;
+ int max_width = -1;
+ int min_width = -1;
- if (item != null)
- item.Focused = true;
-
- focused_item = item;
+ int max_height = -1;
+ int min_height = -1;
+
+ int old_number_lines = 1;
+
+ SizeF text_size_one_char;
+
+ public ListViewLabelEditTextBox ()
+ {
+ min_height = DefaultSize.Height;
+ text_size_one_char = DeviceContext.MeasureString ("B", Font);
+ }
+
+ public int MaxWidth {
+ set {
+ if (value < min_width)
+ max_width = min_width;
+ else
+ max_width = value;
+ }
+ }
+
+ public int MaxHeight {
+ set {
+ if (value < min_height)
+ max_height = min_height;
+ else
+ max_height = value;
+ }
+ }
+
+ public new int Width {
+ get {
+ return base.Width;
+ }
+ set {
+ min_width = value;
+ base.Width = value;
+ }
+ }
+
+ public override Font Font {
+ get {
+ return base.Font;
+ }
+ set {
+ base.Font = value;
+ text_size_one_char = DeviceContext.MeasureString ("B", Font);
+ }
+ }
+
+ protected override void OnTextChanged (EventArgs e)
+ {
+ SizeF text_size = DeviceContext.MeasureString (Text, Font);
+
+ int new_width = (int)text_size.Width + 8;
+
+ if (!Multiline)
+ ResizeTextBoxWidth (new_width);
+ else {
+ if (Width != max_width)
+ ResizeTextBoxWidth (new_width);
+
+ int number_lines = Lines.Length;
+
+ if (number_lines != old_number_lines) {
+ int new_height = number_lines * (int)text_size_one_char.Height + 4;
+ old_number_lines = number_lines;
+
+ ResizeTextBoxHeight (new_height);
+ }
+ }
+
+ base.OnTextChanged (e);
+ }
+
+ protected override bool IsInputKey (Keys key_data)
+ {
+ if ((key_data & Keys.Alt) == 0) {
+ switch (key_data & Keys.KeyCode) {
+ case Keys.Enter:
+ return true;
+ }
+ }
+ return base.IsInputKey (key_data);
+ }
+
+ protected override void OnKeyDown (KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Return && Visible) {
+ this.Visible = false;
+ OnEditingFinished (e);
+ }
+ }
+
+ protected override void OnLostFocus (EventArgs e)
+ {
+ if (Visible) {
+ OnEditingFinished (e);
+ }
+ }
+
+ protected void OnEditingFinished (EventArgs e)
+ {
+ EventHandler eh = (EventHandler)(Events [EditingFinishedEvent]);
+ if (eh != null)
+ eh (this, e);
+ }
+
+ private void ResizeTextBoxWidth (int new_width)
+ {
+ if (new_width > max_width)
+ base.Width = max_width;
+ else
+ if (new_width >= min_width)
+ base.Width = new_width;
+ else
+ base.Width = min_width;
+ }
+
+ private void ResizeTextBoxHeight (int new_height)
+ {
+ if (new_height > max_height)
+ base.Height = max_height;
+ else
+ if (new_height >= min_height)
+ base.Height = new_height;
+ else
+ base.Height = min_height;
+ }
+
+ public void Reset ()
+ {
+ max_width = -1;
+ min_width = -1;
+
+ max_height = -1;
+
+ old_number_lines = 1;
+
+ Text = String.Empty;
+
+ Size = DefaultSize;
+ }
+
+ static object EditingFinishedEvent = new object ();
+ public event EventHandler EditingFinished {
+ add { Events.AddHandler (EditingFinishedEvent, value); }
+ remove { Events.RemoveHandler (EditingFinishedEvent, value); }
+ }
+ }
+
+ internal override void OnPaintInternal (PaintEventArgs pe)
+ {
+ if (updating)
+ return;
+
+ CalculateScrollBars ();
+ }
+
+ void FocusChanged (object o, EventArgs args)
+ {
+ if (Items.Count == 0)
+ return;
+
+ if (FocusedItem == null)
+ SetFocusedItem (Items [0]);
+
+ item_control.Invalidate (FocusedItem.Bounds);
+ }
+
+ private void ListView_MouseWheel (object sender, MouseEventArgs me)
+ {
+ if (Items.Count == 0)
+ return;
+
+ int lines = me.Delta / 120;
+
+ if (lines == 0)
+ return;
+
+ switch (View) {
+ case View.Details:
+ case View.SmallIcon:
+ Scroll (v_scroll, -Items [0].Bounds.Height * SystemInformation.MouseWheelScrollLines * lines);
+ break;
+ case View.LargeIcon:
+ Scroll (v_scroll, -(Items [0].Bounds.Height + ThemeEngine.Current.ListViewVerticalSpacing) * lines);
+ break;
+ case View.List:
+ Scroll (h_scroll, -Items [0].Bounds.Width * lines);
+ break;
+ }
+ }
+
+ private void ListView_SizeChanged (object sender, EventArgs e)
+ {
+ CalculateListView (alignment);
+ }
+
+ private void SetFocusedItem (ListViewItem item)
+ {
+ if (focused_item != null)
+ focused_item.Focused = false;
+
+ if (item != null)
+ item.Focused = true;
+
+ focused_item = item;
}
private void HorizontalScroller (object sender, EventArgs e)
{
+ item_control.EndEdit (item_control.edit_item);
+
// Avoid unnecessary flickering, when button is
// kept pressed at the end
if (h_marker != h_scroll.Value) {
private void VerticalScroller (object sender, EventArgs e)
{
+ item_control.EndEdit (item_control.edit_item);
+
// Avoid unnecessary flickering, when button is
// kept pressed at the end
if (v_marker != v_scroll.Value) {
protected override void CreateHandle ()
{
base.CreateHandle ();
+ for (int i = 0; i < SelectedItems.Count; i++)
+ OnSelectedIndexChanged (EventArgs.Empty);
}
protected override void Dispose (bool disposing)
protected virtual void OnAfterLabelEdit (LabelEditEventArgs e)
{
- if (AfterLabelEdit != null)
- AfterLabelEdit (this, e);
+ LabelEditEventHandler eh = (LabelEditEventHandler)(Events [AfterLabelEditEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnBeforeLabelEdit (LabelEditEventArgs e)
{
- if (BeforeLabelEdit != null)
- BeforeLabelEdit (this, e);
+ LabelEditEventHandler eh = (LabelEditEventHandler)(Events [BeforeLabelEditEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnColumnClick (ColumnClickEventArgs e)
{
- if (ColumnClick != null)
- ColumnClick (this, e);
+ ColumnClickEventHandler eh = (ColumnClickEventHandler)(Events [ColumnClickEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected override void OnEnabledChanged (EventArgs e)
protected override void OnHandleCreated (EventArgs e)
{
base.OnHandleCreated (e);
+ Sort ();
}
protected override void OnHandleDestroyed (EventArgs e)
protected virtual void OnItemActivate (EventArgs e)
{
- if (ItemActivate != null)
- ItemActivate (this, e);
+ EventHandler eh = (EventHandler)(Events [ItemActivateEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnItemCheck (ItemCheckEventArgs ice)
{
- if (ItemCheck != null)
- ItemCheck (this, ice);
+ EventHandler eh = (EventHandler)(Events [ItemCheckEvent]);
+ if (eh != null)
+ eh (this, ice);
}
protected virtual void OnItemDrag (ItemDragEventArgs e)
{
- if (ItemDrag != null)
- ItemDrag (this, e);
+ EventHandler eh = (EventHandler)(Events [ItemDragEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnSelectedIndexChanged (EventArgs e)
{
- if (SelectedIndexChanged != null)
- SelectedIndexChanged (this, e);
+ EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected override void OnSystemColorsChanged (EventArgs e)
// 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;
public void Sort ()
{
- if (sort_order != SortOrder.None)
- items.list.Sort (item_sorter);
-
- if (sort_order == SortOrder.Descending)
- items.list.Reverse ();
+ Sort (true);
+ }
- this.Redraw (true);
+ // we need this overload to reuse the logic for sorting, while allowing
+ // redrawing to be done by caller or have it done by this method when
+ // sorting is really performed
+ //
+ // ListViewItemCollection's Add and AddRange methods call this overload
+ // with redraw set to false, as they take care of redrawing themselves
+ // (they even want to redraw the listview if no sort is performed, as
+ // an item was added), while ListView.Sort () only wants to redraw if
+ // sorting was actually performed
+ private void Sort (bool redraw)
+ {
+ if (!IsHandleCreated || item_sorter == null) {
+ return;
+ }
+
+ items.Sort (item_sorter);
+ if (redraw)
+ this.Redraw (true);
}
public override string ToString ()
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);
}
private class ItemComparer : IComparer {
+ readonly SortOrder sort_order;
+
+ public ItemComparer (SortOrder sortOrder)
+ {
+ sort_order = sortOrder;
+ }
public int Compare (object x, object y)
{
ListViewItem item_x = x as ListViewItem;
ListViewItem item_y = y as ListViewItem;
- return String.Compare (item_x.Text, item_y.Text);
+ if (sort_order == SortOrder.Ascending)
+ return String.Compare (item_x.Text, item_y.Text);
+ else
+ return String.Compare (item_y.Text, item_x.Text);
}
}
public class CheckedIndexCollection : IList, ICollection, IEnumerable
{
- internal ArrayList list;
- private ListView owner;
+ private readonly ListView owner;
#region Public Constructor
public CheckedIndexCollection (ListView owner)
{
- list = new ArrayList ();
this.owner = owner;
}
#endregion // Public Constructor
#region Public Properties
[Browsable (false)]
public int Count {
- get { return list.Count; }
+ get { return owner.CheckedItems.Count; }
}
public bool IsReadOnly {
public int this [int index] {
get {
- if (index < 0 || index >= list.Count)
+ int [] indices = GetIndices ();
+ if (index < 0 || index >= indices.Length)
throw new ArgumentOutOfRangeException ("index");
- return (int) list [index];
+ return indices [index];
}
}
#region Public Methods
public bool Contains (int checkedIndex)
{
- return list.Contains (checkedIndex);
+ int [] indices = GetIndices ();
+ for (int i = 0; i < indices.Length; i++) {
+ if (indices [i] == checkedIndex)
+ return true;
+ }
+ return false;
}
public IEnumerator GetEnumerator ()
{
- return list.GetEnumerator ();
+ int [] indices = GetIndices ();
+ return indices.GetEnumerator ();
}
void ICollection.CopyTo (Array dest, int index)
{
- list.CopyTo (dest, index);
+ int [] indices = GetIndices ();
+ Array.Copy (indices, 0, dest, index, indices.Length);
}
int IList.Add (object value)
bool IList.Contains (object checkedIndex)
{
- return list.Contains (checkedIndex);
+ if (!(checkedIndex is int))
+ return false;
+ return Contains ((int) checkedIndex);
}
int IList.IndexOf (object checkedIndex)
{
- return list.IndexOf (checkedIndex);
+ if (!(checkedIndex is int))
+ return -1;
+ return IndexOf ((int) checkedIndex);
}
void IList.Insert (int index, object value)
public int IndexOf (int checkedIndex)
{
- return list.IndexOf (checkedIndex);
+ int [] indices = GetIndices ();
+ for (int i = 0; i < indices.Length; i++) {
+ if (indices [i] == checkedIndex)
+ return i;
+ }
+ return -1;
}
#endregion // Public Methods
+ private int [] GetIndices ()
+ {
+ ArrayList checked_items = owner.CheckedItems.List;
+ int [] indices = new int [checked_items.Count];
+ for (int i = 0; i < checked_items.Count; i++) {
+ ListViewItem item = (ListViewItem) checked_items [i];
+ indices [i] = item.Index;
+ }
+ return indices;
+ }
} // CheckedIndexCollection
public class CheckedListViewItemCollection : IList, ICollection, IEnumerable
{
- internal ArrayList list;
- private ListView owner;
+ private readonly ListView owner;
+ private ArrayList list;
#region Public Constructor
public CheckedListViewItemCollection (ListView owner)
{
- list = new ArrayList ();
this.owner = owner;
+ this.owner.Items.Changed += new CollectionChangedHandler (
+ ItemsCollection_Changed);
}
#endregion // Public Constructor
#region Public Properties
[Browsable (false)]
public int Count {
- get { return list.Count; }
+ get {
+ if (!owner.CheckBoxes)
+ return 0;
+ return List.Count;
+ }
}
public bool IsReadOnly {
public ListViewItem this [int index] {
get {
- if (index < 0 || index >= list.Count)
+ ArrayList checked_items = List;
+ if (index < 0 || index >= checked_items.Count)
throw new ArgumentOutOfRangeException ("index");
- return (ListViewItem) list [index];
+ return (ListViewItem) checked_items [index];
+ }
+ }
+
+#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 list.IsSynchronized; }
+ get { return false; }
}
object ICollection.SyncRoot {
#region Public Methods
public bool Contains (ListViewItem item)
{
- return list.Contains (item);
+ if (!owner.CheckBoxes)
+ 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)
{
- list.CopyTo (dest, index);
+ if (!owner.CheckBoxes)
+ return;
+ List.CopyTo (dest, index);
}
public IEnumerator GetEnumerator ()
{
- return list.GetEnumerator ();
+ if (!owner.CheckBoxes)
+ return (new ListViewItem [0]).GetEnumerator ();
+ return List.GetEnumerator ();
}
int IList.Add (object value)
bool IList.Contains (object item)
{
- return list.Contains (item);
+ if (!(item is ListViewItem))
+ return false;
+ return Contains ((ListViewItem) item);
}
int IList.IndexOf (object item)
{
- return list.IndexOf (item);
+ if (!(item is ListViewItem))
+ return -1;
+ return IndexOf ((ListViewItem) item);
}
void IList.Insert (int index, object value)
public int IndexOf (ListViewItem item)
{
- return list.IndexOf (item);
+ 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 {
+ get {
+ if (list == null) {
+ list = new ArrayList ();
+ foreach (ListViewItem item in owner.Items) {
+ if (item.Checked)
+ list.Add (item);
+ }
+ }
+ return list;
+ }
+ }
+
+ internal void Reset ()
+ {
+ // force re-population of list
+ list = null;
+ }
+
+ private void ItemsCollection_Changed ()
+ {
+ Reset ();
+ }
} // CheckedListViewItemCollection
public class ColumnHeaderCollection : IList, ICollection, IEnumerable
}
}
+#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;
}
- public virtual void AddRange (ColumnHeader [] values)
+#if NET_2_0
+ public virtual ColumnHeader Add (string text)
{
- foreach (ColumnHeader colHeader in values) {
- colHeader.owner = this.owner;
- Add (colHeader);
- }
-
- owner.Redraw (true);
+ return Add (String.Empty, text);
}
- public virtual void Clear ()
+ public virtual ColumnHeader Add (string text, int iwidth)
{
- list.Clear ();
- owner.Redraw (true);
+ 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.SetListView (this.owner);
+ Add (colHeader);
+ }
+
+ owner.Redraw (true);
+ }
+
+ public virtual void Clear ()
+ {
+ list.Clear ();
+ owner.Redraw (true);
}
public bool Contains (ColumnHeader value)
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)
public class ListViewItemCollection : IList, ICollection, IEnumerable
{
- internal ArrayList list;
- private ListView owner;
+ private readonly ArrayList list;
+ private readonly ListView owner;
#region Public Constructor
public ListViewItemCollection (ListView owner)
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 ();
owner.Redraw (true);
}
}
+#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; }
}
this [index] = (ListViewItem) value;
else
this [index] = new ListViewItem (value.ToString ());
+ OnChange ();
}
}
#endregion // Public Properties
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);
- if (owner.Sorting != SortOrder.None)
- owner.Sort ();
-
- 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 ();
- owner.SelectedItems.list.Clear ();
- owner.SelectedIndices.list.Clear ();
- owner.CheckedItems.list.Clear ();
- owner.CheckedIndices.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);
}
+ }
- if (owner.Sorting != SortOrder.None)
- owner.Sort ();
+#if NET_2_0
+ public void AddRange (ListViewItemCollection items)
+ {
+ if (items == null)
+ throw new ArgumentNullException ("Argument cannot be null!", "items");
- owner.Redraw (true);
+ ListViewItem[] itemArray = new ListViewItem[items.Count];
+ items.CopyTo (itemArray,0);
+ this.AddRange (itemArray);
}
+#endif
public virtual void Clear ()
{
owner.SetFocusedItem (null);
owner.h_scroll.Value = owner.v_scroll.Value = 0;
list.Clear ();
- owner.SelectedItems.list.Clear ();
- owner.SelectedIndices.list.Clear ();
- owner.CheckedItems.list.Clear ();
- owner.CheckedIndices.list.Clear ();
+ OnChange ();
owner.Redraw (true);
}
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 ());
li.Owner = owner;
result = list.Add (li);
+ OnChange ();
owner.Redraw (true);
return result;
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)
{
- // LAMESPEC: MSDOCS say greater than or equal to the value of the Count property
- // but it's really only greater.
if (index < 0 || index > list.Count)
throw new ArgumentOutOfRangeException ("index");
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 ();
owner.Redraw (true);
return item;
}
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))
return;
- owner.SelectedItems.list.Remove (item);
- owner.SelectedIndices.list.Remove (item.Index);
- owner.CheckedItems.list.Remove (item);
- owner.CheckedIndices.list.Remove (item.Index);
+ bool selection_changed = owner.SelectedItems.Contains (item);
list.Remove (item);
+ OnChange ();
owner.Redraw (true);
+ if (selection_changed)
+ owner.OnSelectedIndexChanged (EventArgs.Empty);
}
public virtual void RemoveAt (int index)
{
- if (index < 0 || index >= list.Count)
+ if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException ("index");
-
+ bool selection_changed = owner.SelectedIndices.Contains (index);
list.RemoveAt (index);
- owner.SelectedItems.list.RemoveAt (index);
- owner.SelectedIndices.list.RemoveAt (index);
- owner.CheckedItems.list.RemoveAt (index);
- owner.CheckedIndices.list.RemoveAt (index);
+ OnChange ();
owner.Redraw (false);
+ 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;
+
+ internal void Sort (IComparer comparer)
+ {
+ list.Sort (comparer);
+ OnChange ();
+ }
+
+ internal void OnChange ()
+ {
+ if (Changed != null)
+ Changed ();
+ }
} // ListViewItemCollection
public class SelectedIndexCollection : IList, ICollection, IEnumerable
{
- internal ArrayList list;
- private ListView owner;
+ private readonly ListView owner;
#region Public Constructor
public SelectedIndexCollection (ListView owner)
{
- list = new ArrayList ();
this.owner = owner;
}
#endregion // Public Constructor
#region Public Properties
[Browsable (false)]
public int Count {
- get { return list.Count; }
+ get {
+ return owner.SelectedItems.Count;
+ }
}
public bool IsReadOnly {
- get { return true; }
+ get {
+#if NET_2_0
+ return false;
+#else
+ return true;
+#endif
+ }
}
public int this [int index] {
get {
- if (index < 0 || index >= list.Count)
+ int [] indices = GetIndices ();
+ if (index < 0 || index >= indices.Length)
throw new ArgumentOutOfRangeException ("index");
- return (int) list [index];
+ return indices [index];
}
}
bool ICollection.IsSynchronized {
- get { return list.IsSynchronized; }
+ get { return false; }
}
object ICollection.SyncRoot {
}
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)
{
- return list.Contains (selectedIndex);
+ int [] indices = GetIndices ();
+ for (int i = 0; i < indices.Length; i++) {
+ if (indices [i] == selectedIndex)
+ return true;
+ }
+ return false;
}
public void CopyTo (Array dest, int index)
{
- list.CopyTo (dest, index);
+ int [] indices = GetIndices ();
+ Array.Copy (indices, 0, dest, index, indices.Length);
}
public IEnumerator GetEnumerator ()
{
- return list.GetEnumerator ();
+ int [] indices = GetIndices ();
+ return indices.GetEnumerator ();
}
int IList.Add (object value)
bool IList.Contains (object selectedIndex)
{
- return list.Contains (selectedIndex);
+ if (!(selectedIndex is int))
+ return false;
+ return Contains ((int) selectedIndex);
}
int IList.IndexOf (object selectedIndex)
{
- return list.IndexOf (selectedIndex);
+ if (!(selectedIndex is int))
+ return -1;
+ return IndexOf ((int) selectedIndex);
}
void IList.Insert (int index, object value)
public int IndexOf (int selectedIndex)
{
- return list.IndexOf (selectedIndex);
+ int [] indices = GetIndices ();
+ for (int i = 0; i < indices.Length; i++) {
+ if (indices [i] == selectedIndex)
+ return i;
+ }
+ 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 ()
+ {
+ ArrayList selected_items = owner.SelectedItems.List;
+ int [] indices = new int [selected_items.Count];
+ for (int i = 0; i < selected_items.Count; i++) {
+ ListViewItem item = (ListViewItem) selected_items [i];
+ indices [i] = item.Index;
+ }
+ return indices;
+ }
} // SelectedIndexCollection
public class SelectedListViewItemCollection : IList, ICollection, IEnumerable
{
- internal ArrayList list;
- private ListView owner;
+ private readonly ListView owner;
+ private ArrayList list;
#region Public Constructor
public SelectedListViewItemCollection (ListView owner)
{
- list = new ArrayList ();
this.owner = owner;
+ this.owner.Items.Changed += new CollectionChangedHandler (
+ ItemsCollection_Changed);
}
#endregion // Public Constructor
#region Public Properties
[Browsable (false)]
public int Count {
- get { return list.Count; }
+ get {
+ if (!owner.IsHandleCreated)
+ return 0;
+ return List.Count;
+ }
}
public bool IsReadOnly {
public ListViewItem this [int index] {
get {
- if (index < 0 || index >= list.Count)
+ ArrayList selected_items = List;
+ if (!owner.IsHandleCreated || index < 0 || index >= selected_items.Count)
throw new ArgumentOutOfRangeException ("index");
- return (ListViewItem) list [index];
+ return (ListViewItem) selected_items [index];
+ }
+ }
+
+#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 list.IsSynchronized; }
+ get { return false; }
}
object ICollection.SyncRoot {
#region Public Methods
public void Clear ()
{
- ArrayList copy = (ArrayList) list.Clone ();
- for (int i = 0; i < copy.Count; i++)
- ((ListViewItem) copy [i]).Selected = false;
+ if (!owner.IsHandleCreated)
+ return;
- list.Clear ();
+ foreach (ListViewItem item in List)
+ item.Selected = false;
}
public bool Contains (ListViewItem item)
{
- return list.Contains (item);
+ if (!owner.IsHandleCreated)
+ 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)
{
- list.CopyTo (dest, index);
+ if (!owner.IsHandleCreated)
+ return;
+ List.CopyTo (dest, index);
}
public IEnumerator GetEnumerator ()
{
- return list.GetEnumerator ();
+ if (!owner.IsHandleCreated)
+ return (new ListViewItem [0]).GetEnumerator ();
+ return List.GetEnumerator ();
}
int IList.Add (object value)
bool IList.Contains (object item)
{
- return list.Contains (item);
+ if (!(item is ListViewItem))
+ return false;
+ return Contains ((ListViewItem) item);
}
int IList.IndexOf (object item)
{
- return list.IndexOf (item);
+ if (!(item is ListViewItem))
+ return -1;
+ return IndexOf ((ListViewItem) item);
}
void IList.Insert (int index, object value)
public int IndexOf (ListViewItem item)
{
- return list.IndexOf (item);
+ 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 {
+ get {
+ if (list == null) {
+ list = new ArrayList ();
+ foreach (ListViewItem item in owner.Items) {
+ if (item.Selected)
+ list.Add (item);
+ }
+ }
+ return list;
+ }
+ }
+
+ internal void Reset ()
+ {
+ // force re-population of list
+ list = null;
+ }
+
+ private void ItemsCollection_Changed ()
+ {
+ Reset ();
+ }
} // SelectedListViewItemCollection
+ 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
}
}