Properly update the combo box selected text when the current item is changed, and...
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListView.cs
index 95e5a735b04ef9c96d3a48ec865123ade8a13e72..c1b7d791f8d2974c14d91a11622fb822eee0dafa 100644 (file)
@@ -37,20 +37,16 @@ using System.ComponentModel.Design;
 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;
@@ -69,11 +65,9 @@ namespace System.Windows.Forms
                private bool hover_selection;
                private IComparer item_sorter;
                private readonly ListViewItemCollection items;
-#if NET_2_0
                private readonly ListViewGroupCollection groups;
                private bool owner_draw;
                private bool show_groups = true;
-#endif
                private bool label_edit;
                private bool label_wrap = true;
                private bool multiselect = true;
@@ -103,7 +97,6 @@ namespace System.Windows.Forms
                private Size item_size; // used for caching item size
                private int custom_column_width; // used when using Columns with SmallIcon/List views
                private int hot_item_index = -1;
-#if NET_2_0
                private bool hot_tracking;
                private ListViewInsertionMark insertion_mark;
                private bool show_item_tooltips;
@@ -112,7 +105,9 @@ namespace System.Windows.Forms
                private bool virtual_mode;
                private int virtual_list_size;
                private bool right_to_left_layout;
-#endif
+               // selection is available after the first time the handle is created, *even* if later
+               // the handle is either recreated or destroyed - so keep this info around.
+               private bool is_selection_available;
 
                // internal variables
                internal ImageList large_image_list;
@@ -127,7 +122,6 @@ namespace System.Windows.Forms
                static object ItemCheckEvent = new object ();
                static object ItemDragEvent = new object ();
                static object SelectedIndexChangedEvent = new object ();
-#if NET_2_0
                static object DrawColumnHeaderEvent = new object();
                static object DrawItemEvent = new object();
                static object DrawSubItemEvent = new object();
@@ -139,30 +133,19 @@ namespace System.Windows.Forms
                static object RightToLeftLayoutChangedEvent = new object ();
                static object SearchForVirtualItemEvent = new object ();
                static object VirtualItemsSelectionRangeChangedEvent = new object ();
-#endif
 
                public event LabelEditEventHandler AfterLabelEdit {
                        add { Events.AddHandler (AfterLabelEditEvent, value); }
                        remove { Events.RemoveHandler (AfterLabelEditEvent, value); }
                }
 
-#if !NET_2_0
-               [Browsable (false)]
-               [EditorBrowsable (EditorBrowsableState.Never)]
-               public new event EventHandler BackgroundImageChanged {
-                       add { base.BackgroundImageChanged += value; }
-                       remove { base.BackgroundImageChanged -= value; }
-               }
-#endif
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public new event EventHandler BackgroundImageLayoutChanged {
                        add { base.BackgroundImageLayoutChanged += value; }
                        remove { base.BackgroundImageLayoutChanged -= value; }
                }
-#endif
 
                public event LabelEditEventHandler BeforeLabelEdit {
                        add { Events.AddHandler (BeforeLabelEditEvent, value); }
@@ -174,7 +157,6 @@ namespace System.Windows.Forms
                        remove { Events.RemoveHandler (ColumnClickEvent, value); }
                }
 
-#if NET_2_0
                public event DrawListViewColumnHeaderEventHandler DrawColumnHeader {
                        add { Events.AddHandler(DrawColumnHeaderEvent, value); }
                        remove { Events.RemoveHandler(DrawColumnHeaderEvent, value); }
@@ -189,7 +171,6 @@ namespace System.Windows.Forms
                        add { Events.AddHandler(DrawSubItemEvent, value); }
                        remove { Events.RemoveHandler(DrawSubItemEvent, value); }
                }
-#endif
 
                public event EventHandler ItemActivate {
                        add { Events.AddHandler (ItemActivateEvent, value); }
@@ -201,19 +182,16 @@ namespace System.Windows.Forms
                        remove { Events.RemoveHandler (ItemCheckEvent, value); }
                }
 
-#if NET_2_0
                public event ItemCheckedEventHandler ItemChecked {
                        add { Events.AddHandler (ItemCheckedEvent, value); }
                        remove { Events.RemoveHandler (ItemCheckedEvent, value); }
                }
-#endif
 
                public event ItemDragEventHandler ItemDrag {
                        add { Events.AddHandler (ItemDragEvent, value); }
                        remove { Events.RemoveHandler (ItemDragEvent, value); }
                }
 
-#if NET_2_0
                public event ListViewItemMouseHoverEventHandler ItemMouseHover {
                        add { Events.AddHandler (ItemMouseHoverEvent, value); }
                        remove { Events.RemoveHandler (ItemMouseHoverEvent, value); }
@@ -230,7 +208,6 @@ namespace System.Windows.Forms
                        add { base.PaddingChanged += value; }
                        remove { base.PaddingChanged -= value; }
                }
-#endif
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
@@ -251,7 +228,6 @@ namespace System.Windows.Forms
                        remove { base.TextChanged -= value; }
                }
 
-#if NET_2_0
                public event CacheVirtualItemsEventHandler CacheVirtualItems {
                        add { Events.AddHandler (CacheVirtualItemsEvent, value); }
                        remove { Events.RemoveHandler (CacheVirtualItemsEvent, value); }
@@ -276,7 +252,6 @@ namespace System.Windows.Forms
                        add { Events.AddHandler (VirtualItemsSelectionRangeChangedEvent, value); }
                        remove { Events.RemoveHandler (VirtualItemsSelectionRangeChangedEvent, value); }
                }
-#endif
 
                #endregion // Events
 
@@ -284,9 +259,7 @@ namespace System.Windows.Forms
                public ListView ()
                {
                        background_color = ThemeEngine.Current.ColorWindow;
-#if NET_2_0
                        groups = new ListViewGroupCollection (this);
-#endif
                        items = new ListViewItemCollection (this);
                        items.Changed += new CollectionChangedHandler (OnItemsChanged);
                        checked_indices = new CheckedIndexCollection (this);
@@ -298,11 +271,9 @@ namespace System.Windows.Forms
                        items_location = new Point [16];
                        items_matrix_location = new ItemMatrixLocation [16];
                        reordered_items_indices = new int [16];
-#if NET_2_0
                        item_tooltip = new ToolTip ();
                        item_tooltip.Active = false;
                        insertion_mark = new ListViewInsertionMark (this);
-#endif
 
                        InternalBorderStyle = BorderStyle.Fixed3D;
 
@@ -337,14 +308,10 @@ namespace System.Windows.Forms
                        MouseEnter += new EventHandler (ListView_MouseEnter);
                        Invalidated += new InvalidateEventHandler (ListView_Invalidated);
 
-#if NET_2_0
                        BackgroundImageTiled = false;
-#endif
 
                        this.SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick
-#if NET_2_0
                                | ControlStyles.UseTextForAccessibility
-#endif
                                , false);
                }
                #endregion      // Public Constructors
@@ -388,6 +355,13 @@ namespace System.Windows.Forms
                        }
                }
 
+               internal bool UsingGroups {
+                       get {
+                               return show_groups && groups.Count > 0 && view != View.List && 
+                                       Application.VisualStylesEnabled;
+                       }
+               }
+
                internal override bool ScaleChildrenInternal {
                        get { return false; }
                }
@@ -413,7 +387,6 @@ namespace System.Windows.Forms
                protected override Size DefaultSize {
                        get { return ThemeEngine.Current.ListViewDefaultSize; }
                }
-#if NET_2_0
                protected override bool DoubleBuffered {
                        get {
                                return base.DoubleBuffered;
@@ -422,7 +395,6 @@ namespace System.Windows.Forms
                                base.DoubleBuffered = value;
                        }
                }
-#endif
                #endregion      // Protected Properties
 
                #region Public Instance Properties
@@ -435,10 +407,8 @@ namespace System.Windows.Forms
                                        throw new InvalidEnumArgumentException (string.Format
                                                ("Enum argument value '{0}' is not valid for Activation", value));
                                }
-#if NET_2_0
                                if (hot_tracking && value != ItemActivation.OneClick)
                                        throw new ArgumentException ("When HotTracking is on, activation must be ItemActivation.OneClick");
-#endif
                                
                                activation = value;
                        }
@@ -496,16 +466,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if !NET_2_0
-               [Browsable (false)]
-               [EditorBrowsable (EditorBrowsableState.Never)]
-               public override Image BackgroundImage {
-                       get { return base.BackgroundImage; }
-                       set { base.BackgroundImage = value; }
-               }
-#endif
-
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public override ImageLayout BackgroundImageLayout {
@@ -530,7 +490,6 @@ namespace System.Windows.Forms
                                item_control.BackgroundImageLayout = new_image_layout;
                        }
                }
-#endif
 
                [DefaultValue (BorderStyle.Fixed3D)]
                [DispId (-504)]
@@ -544,20 +503,16 @@ namespace System.Windows.Forms
                        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);
 
-#if NET_2_0
                                        //UIA Framework: Event used by ListView to set/unset Toggle Pattern
                                        OnUIACheckBoxesChanged ();
-#endif
                                }
                        }
                }
@@ -574,9 +529,7 @@ namespace System.Windows.Forms
                        get { return checked_items; }
                }
 
-#if NET_2_0
                [Editor ("System.Windows.Forms.Design.ColumnHeaderCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-#endif
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [Localizable (true)]
                [MergableProperty (false)]
@@ -593,7 +546,6 @@ namespace System.Windows.Forms
 
                                return GetItemAtDisplayIndex (focused_item_index);
                        }
-#if NET_2_0
                        set {
                                if (value == null || value.ListView != this || 
                                                !IsHandleCreated)
@@ -601,7 +553,6 @@ namespace System.Windows.Forms
 
                                SetFocusedItem (value.DisplayIndex);
                        }
-#endif
                }
 
                public override Color ForeColor {
@@ -670,7 +621,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [DefaultValue (false)]
                public bool HotTracking {
                        get {
@@ -687,21 +637,17 @@ namespace System.Windows.Forms
                                }
                        }
                }
-#endif
 
                [DefaultValue (false)]
                public bool HoverSelection {
                        get { return hover_selection; }
                        set { 
-#if NET_2_0
                                if (hot_tracking && value == false)
                                        throw new ArgumentException ("When HotTracking is on, hover selection must be true");
-#endif
                                hover_selection = value; 
                        }
                }
 
-#if NET_2_0
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [Browsable (false)]
                public ListViewInsertionMark InsertionMark {
@@ -709,11 +655,8 @@ namespace System.Windows.Forms
                                return insertion_mark;
                        }
                }
-#endif
 
-#if NET_2_0
                [Editor ("System.Windows.Forms.Design.ListViewItemCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-#endif
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [Localizable (true)]
                [MergableProperty (false)]
@@ -728,10 +671,8 @@ namespace System.Windows.Forms
                                if (value != label_edit) {
                                        label_edit = value; 
 
-#if NET_2_0
                                        // UIA Framework: Event used by Value Pattern in ListView.ListItem provider
                                        OnUIALabelEditChanged ();
-#endif
                                }
 
                        }
@@ -781,16 +722,13 @@ namespace System.Windows.Forms
                                if (value != multiselect) {
                                        multiselect = value; 
 
-#if NET_2_0
                                        // UIA Framework: Event used by Selection Pattern in ListView.ListItem provider
                                        OnUIAMultiSelectChanged ();
-#endif
                                }
                        }
                }
 
 
-#if NET_2_0
                [DefaultValue(false)]
                public bool OwnerDraw {
                        get { return owner_draw; }
@@ -824,7 +762,6 @@ namespace System.Windows.Forms
                                }
                        }
                }
-#endif
 
                [DefaultValue (true)]
                public bool Scrollable {
@@ -849,7 +786,6 @@ namespace System.Windows.Forms
                        get { return selected_items; }
                }
 
-#if NET_2_0
                [DefaultValue(true)]
                public bool ShowGroups {
                        get { return show_groups; }
@@ -882,7 +818,6 @@ namespace System.Windows.Forms
                                item_tooltip.Active = false;
                        }
                }
-#endif
 
                [DefaultValue (null)]
                public ImageList SmallImageList {
@@ -907,39 +842,22 @@ namespace System.Windows.Forms
 
                                sort_order = value;
 
-#if NET_2_0
                                if (virtual_mode) // Sorting is not allowed in virtual mode
                                        return;
-#endif
 
                                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 ();
                                }
@@ -984,7 +902,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [Browsable (true)]
                public Size TileSize {
                        get {
@@ -999,16 +916,13 @@ namespace System.Windows.Forms
                                        Redraw (true);
                        }
                }
-#endif
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public ListViewItem TopItem {
                        get {
-#if NET_2_0
                                if (view == View.LargeIcon || view == View.SmallIcon || view == View.Tile)
                                        throw new InvalidOperationException ("Cannot get the top item in LargeIcon, SmallIcon or Tile view.");
-#endif
                                // there is no item
                                if (this.items.Count == 0)
                                        return null;
@@ -1018,15 +932,15 @@ namespace System.Windows.Forms
                                        return this.items [0];
                                // do a hit test for the scrolled position
                                else {
+                                       int header_offset = header_control.Height;
                                        for (int i = 0; i < items.Count; i++) {
                                                Point item_loc = GetItemLocation (i);
-                                               if (item_loc.X >= 0 && item_loc.Y >= 0)
+                                               if (item_loc.X >= 0 && item_loc.Y - header_offset >= 0)
                                                        return items [i];
                                        }
                                        return null;
                                }
                        }
-#if NET_2_0
                        set {
                                if (view == View.LargeIcon || view == View.SmallIcon || view == View.Tile)
                                        throw new InvalidOperationException ("Cannot set the top item in LargeIcon, SmallIcon or Tile view.");
@@ -1035,12 +949,11 @@ namespace System.Windows.Forms
                                if (value == null || value.ListView != this)
                                        return;
 
-                               EnsureVisible (value.Index);
+                               // Take advantage this property is only valid for Details view.
+                               SetScrollValue (v_scroll, item_size.Height * value.Index);
                        }
-#endif
                }
 
-#if NET_2_0
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                [DefaultValue (true)]
                [Browsable (false)]
@@ -1052,7 +965,6 @@ namespace System.Windows.Forms
                        set {
                        }
                }
-#endif
 
                [DefaultValue (View.LargeIcon)]
                public View View {
@@ -1063,26 +975,25 @@ namespace System.Windows.Forms
                                                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
+                                       if (VirtualMode && value == View.Tile)
+                                               throw new NotSupportedException ("VirtualMode is"
+                                                       + " not supported in Tile view. Choose a different"
+                                                       + " view or set ViewMode to false.");
 
                                        h_scroll.Value = v_scroll.Value = 0;
                                        view = value; 
                                        Redraw (true);
 
-#if NET_2_0
                                        // UIA Framework: Event used to update UIA Tree.
                                        OnUIAViewChanged ();
-#endif
                                }
                        }
                }
 
-#if NET_2_0
                [DefaultValue (false)]
                [RefreshProperties (RefreshProperties.Repaint)]
                public bool VirtualMode {
@@ -1095,6 +1006,10 @@ namespace System.Windows.Forms
 
                                if (!virtual_mode && items.Count > 0)
                                        throw new InvalidOperationException ();
+                               if (value && view == View.Tile)
+                                       throw new NotSupportedException ("VirtualMode is"
+                                               + " not supported in Tile view. Choose a different"
+                                               + " view or set ViewMode to false.");
 
                                virtual_mode = value;
                                Redraw (true);
@@ -1121,7 +1036,6 @@ namespace System.Windows.Forms
                                }
                        }
                }
-#endif
                #endregion      // Public Instance Properties
 
                #region Internal Methods Properties
@@ -1136,6 +1050,27 @@ namespace System.Windows.Forms
                                        return 0;
                                
                                Size item_size = ItemSize;
+                               // In virtual mode we always have fixed positions, and we can infer the positon easily
+                               if (virtual_mode) {
+                                       int first = 0;
+                                       switch (view) {
+                                               case View.Details:
+                                                       first = v_marker / item_size.Height;
+                                                       break;
+                                               case View.LargeIcon:
+                                               case View.SmallIcon:
+                                                       first = (v_marker / (item_size.Height + y_spacing)) * cols;
+                                                       break;
+                                               case View.List:
+                                                       first = (h_marker / (item_size.Width * x_spacing)) * rows;
+                                                       break;
+                                       }
+
+                                       if (first >= items.Count)
+                                               first = items.Count;
+
+                                       return first;
+                               }
                                for (int i = 0; i < items.Count; i++) {
                                        Rectangle item_rect = new Rectangle (GetItemLocation (i), item_size);
                                        if (item_rect.Right >= 0 && item_rect.Bottom >= 0)
@@ -1165,7 +1100,7 @@ namespace System.Windows.Forms
 
                internal void OnSelectedIndexChanged ()
                {
-                       if (IsHandleCreated)
+                       if (is_selection_available)
                                OnSelectedIndexChanged (EventArgs.Empty);
                }
 
@@ -1182,17 +1117,15 @@ namespace System.Windows.Forms
                        // Avoid calculations when control is being updated
                        if (updating)
                                return;
-#if NET_2_0
                        // VirtualMode doesn't do any calculations until handle is created
                        if (virtual_mode && !IsHandleCreated)
                                return;
-#endif
 
 
                        if (recalculate)
                                CalculateListView (this.alignment);
 
-                       Refresh ();
+                       Invalidate (true);
                }
 
                void InvalidateSelection ()
@@ -1246,7 +1179,6 @@ namespace System.Windows.Forms
                {
                        Size temp = Size.Empty;
                        Size ret_size = Size.Empty;
-#if NET_2_0
                        bool use_indent_count = small_image_list != null;
 
                        // VirtualMode uses the first item text size
@@ -1258,7 +1190,6 @@ namespace System.Windows.Forms
                                if (use_indent_count)
                                        ret_size.Width += item.IndentCount * small_image_list.ImageSize.Width;
                        } else {
-#endif
                                // 0th column holds the item text, we check the size of
                                // the various subitems falling in that column and get
                                // the biggest one's size.
@@ -1269,17 +1200,13 @@ namespace System.Windows.Forms
                                        temp = Size.Ceiling (TextRenderer.MeasureString
                                                                (item.SubItems [col].Text, Font));
 
-#if NET_2_0
                                        if (use_indent_count)
                                                temp.Width += item.IndentCount * small_image_list.ImageSize.Width;
-#endif
     
                                        if (temp.Width > ret_size.Width)
                                                ret_size = temp;
                                }
-#if NET_2_0
                        }
-#endif
 
                        // adjustment for space in Details view
                        if (!ret_size.IsEmpty && view == View.Details)
@@ -1335,30 +1262,36 @@ namespace System.Windows.Forms
                        text_size.Height += 2;
                }
 
-               private void Scroll (ScrollBar scrollbar, int delta)
+               private void SetScrollValue (ScrollBar scrollbar, int val)
                {
-                       if (delta == 0 || !scrollbar.Visible)
-                               return;
-
                        int max;
                        if (scrollbar == h_scroll)
-                               max = h_scroll.Maximum - item_control.Width;
+                               max = h_scroll.Maximum - h_scroll.LargeChange + 1;
                        else
-                               max = v_scroll.Maximum - item_control.Height;
+                               max = v_scroll.Maximum - v_scroll.LargeChange + 1;
 
-                       int val = scrollbar.Value + delta;
                        if (val > max)
                                val = max;
                        else if (val < scrollbar.Minimum)
                                val = scrollbar.Minimum;
+
                        scrollbar.Value = val;
                }
 
+               private void Scroll (ScrollBar scrollbar, int delta)
+               {
+                       if (delta == 0 || !scrollbar.Visible)
+                               return;
+
+                       SetScrollValue (scrollbar, scrollbar.Value + delta);
+               }
+
                private void CalculateScrollBars ()
                {
                        Rectangle client_area = ClientRectangle;
                        int height = client_area.Height;
                        int width = client_area.Width;
+                       Size item_size;
                        
                        if (!scrollable) {
                                h_scroll.Visible = false;
@@ -1392,6 +1325,8 @@ namespace System.Windows.Forms
                        }
 
 
+                       item_size = ItemSize;
+
                        if (h_scroll.is_visible) {
                                h_scroll.Location = new Point (client_area.X, client_area.Bottom - h_scroll.Height);
                                h_scroll.Minimum = 0;
@@ -1407,25 +1342,38 @@ namespace System.Windows.Forms
                                        h_scroll.Width = client_area.Width;
                                }
 
+                               if (view == View.List)
+                                       h_scroll.SmallChange = item_size.Width + ThemeEngine.Current.ListViewHorizontalSpacing;
+                               else
+                                       h_scroll.SmallChange = Font.Height;
+
                                h_scroll.LargeChange = client_area.Width;
-                               h_scroll.SmallChange = item_size.Width + ThemeEngine.Current.ListViewHorizontalSpacing;
                                height -= h_scroll.Height;
                        }
 
                        if (v_scroll.is_visible) {
                                v_scroll.Location = new Point (client_area.Right - v_scroll.Width, client_area.Y);
                                v_scroll.Minimum = 0;
-                               v_scroll.Maximum = layout_ht;
 
                                // if h_scroll is visible, adjust the height of
                                // v_scroll to account for the height of h_scroll
-                               if (h_scroll.Visible)
-                                       v_scroll.Height = client_area.Height - h_scroll.Height;
-                               else
+                               if (h_scroll.Visible) {
+                                       v_scroll.Maximum = layout_ht + h_scroll.Height;
+                                       v_scroll.Height = client_area.Height > h_scroll.Height ? client_area.Height - h_scroll.Height : 0;
+                               } else {
+                                       v_scroll.Maximum = layout_ht;
                                        v_scroll.Height = client_area.Height;
+                               }
+
+                               if (view == View.Details) {
+                                       // Need to update Maximum if using LargeChange with value other than the visible area
+                                       int headerPlusOneItem = header_control.Height + item_size.Height;
+                                       v_scroll.LargeChange = v_scroll.Height > headerPlusOneItem ? v_scroll.Height - headerPlusOneItem : 0;
+                                       v_scroll.Maximum = v_scroll.Maximum > headerPlusOneItem ? v_scroll.Maximum - headerPlusOneItem : 0;
+                               } else
+                                       v_scroll.LargeChange = v_scroll.Height;
 
-                               v_scroll.LargeChange = client_area.Height;
-                               v_scroll.SmallChange = Font.Height;
+                               v_scroll.SmallChange = item_size.Height;
                                width -= v_scroll.Width;
                        }
                        
@@ -1435,7 +1383,6 @@ namespace System.Windows.Forms
                                header_control.Width = width;
                }
 
-#if NET_2_0
                internal int GetReorderedColumnIndex (ColumnHeader column)
                {
                        if (reordered_column_indices == null)
@@ -1447,7 +1394,6 @@ namespace System.Windows.Forms
 
                        return -1;
                }
-#endif
 
                internal ColumnHeader GetReorderedColumn (int index)
                {
@@ -1459,7 +1405,6 @@ namespace System.Windows.Forms
 
                internal void ReorderColumn (ColumnHeader col, int index, bool fireEvent)
                {
-#if NET_2_0
                        if (fireEvent) {
                                ColumnReorderedEventHandler eh = (ColumnReorderedEventHandler) (Events [ColumnReorderedEvent]);
                                if (eh != null){
@@ -1473,7 +1418,6 @@ namespace System.Windows.Forms
                                        }
                                }
                        }
-#endif
                        int column_count = Columns.Count;
 
                        if (reordered_column_indices == null) {
@@ -1568,7 +1512,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                Size TileItemSize {
                        get {
                                // Calculate tile size if needed
@@ -1586,7 +1529,6 @@ namespace System.Windows.Forms
                                return tile_size;
                        }
                }
-#endif
 
                int GetDetailsItemHeight ()
                {
@@ -1613,7 +1555,7 @@ namespace System.Windows.Forms
                        reordered_items_indices [index] = index;
                }
 
-#if NET_2_0
+
                void ShiftItemsPositions (int from, int to, bool forward)
                {
                        if (forward) {
@@ -1708,8 +1650,10 @@ namespace System.Windows.Forms
 
                        return count;
                }
-#endif
 
+               // cache the spacing to let virtualmode compute the positions on the fly
+               int x_spacing;
+               int y_spacing;
                int rows;
                int cols;
                int[,] item_index_matrix;
@@ -1720,8 +1664,7 @@ namespace System.Windows.Forms
 
                        if (UseCustomColumnWidth)
                                CalculateCustomColumnWidth ();
-#if NET_2_0
-                       if (show_groups && groups.Count > 0 && view != View.List) {
+                       if (UsingGroups) {
                                // When groups are used the alignment is always top-aligned
                                rows = 0;
                                cols = 0;
@@ -1750,7 +1693,6 @@ namespace System.Windows.Forms
                                        items += items_in_group;
                                }
                        } else
-#endif
                        {
                                // Simple matrix if no groups are used
                                if (left_aligned) {
@@ -1795,32 +1737,36 @@ namespace System.Windows.Forms
                        item_control.Visible = true;
                        item_control.Location = Point.Empty;
                        ItemSize = item_size; // Cache item size
+                       this.x_spacing = x_spacing;
+                       this.y_spacing = y_spacing;
 
                        if (items.Count == 0)
                                return;
 
                        Size sz = item_size;
-#if NET_2_0
-                       bool using_groups = show_groups && groups.Count > 0 && view != View.List;
-#endif
 
                        CalculateRowsAndCols (sz, left_aligned, x_spacing, y_spacing);
 
                        layout_wd = UseCustomColumnWidth ? cols * custom_column_width : cols * (sz.Width + x_spacing) - x_spacing;
                        layout_ht = rows * (sz.Height + y_spacing) - y_spacing;
-#if NET_2_0
-                       if (using_groups)
+
+                       if (virtual_mode) { // no actual assignment is needed on items for virtual mode
+                               item_control.Size = new Size (layout_wd, layout_ht);
+                               return;
+                       }
+
+                       bool using_groups = UsingGroups;
+                       if (using_groups) // the groups layout will override layout_ht
                                CalculateGroupsLayout (sz, y_spacing, 0);
-#endif
 
                        int row = 0, col = 0;
                        int x = 0, y = 0;
                        int display_index = 0;
 
                        for (int i = 0; i < items.Count; i++) {
-#if NET_2_0
+                               ListViewItem item = items [i];
                                if (using_groups) {
-                                       ListViewGroup group = items [i].Group;
+                                       ListViewGroup group = item.Group;
                                        if (group == null)
                                                group = groups.DefaultGroup;
 
@@ -1840,7 +1786,6 @@ namespace System.Windows.Forms
                                        item_index_matrix [row + starting_row, col] = i;
 
                                } else
-#endif
                                {
                                        x = UseCustomColumnWidth ? col * custom_column_width : col * (item_size.Width + x_spacing);
                                        y = row * (item_size.Height + y_spacing);
@@ -1862,25 +1807,15 @@ namespace System.Windows.Forms
                                                }
                                        }
                                }
-#if NET_2_0
-                               if (!virtual_mode) 
-#endif
-                               {
-                                       ListViewItem item = items [i];
-                                       item.Layout ();
-                                       item.DisplayIndex = display_index;
-#if NET_2_0                                    
-                                       item.SetPosition (new Point (x, y));
-#endif                                 
-                               }
-
 
+                               item.Layout ();
+                               item.DisplayIndex = display_index;
+                               item.SetPosition (new Point (x, y));
                        }
 
                        item_control.Size = new Size (layout_wd, layout_ht);
                }
 
-#if NET_2_0
                void CalculateGroupsLayout (Size item_size, int y_spacing, int y_origin)
                {
                        int y = y_origin;
@@ -1900,7 +1835,7 @@ namespace System.Windows.Forms
                int LayoutGroupHeader (ListViewGroup group, int y_origin, int item_height, int y_spacing, int rows)
                {
                        Rectangle client_area = ClientRectangle;
-                       int header_height = text_size.Height + 10;
+                       int header_height = Font.Height + 15; // one line height + some padding
 
                        group.HeaderBounds = new Rectangle (0, y_origin, client_area.Width - v_scroll.Width, header_height);
                        group.items_area_location = new Point (0, y_origin + header_height);
@@ -1913,6 +1848,7 @@ namespace System.Windows.Forms
                {
                        int items = 0;
 
+                       groups.DefaultGroup.ItemCount = GetDefaultGroupItems ();
                        for (int i = 0; i < groups.InternalCount; i++) {
                                ListViewGroup group = groups.GetInternalGroup (i);
                                int items_in_group = group.GetActualItemCount ();
@@ -1925,7 +1861,6 @@ namespace System.Windows.Forms
                                items += items_in_group;
                        }
                }
-#endif
 
                void LayoutHeader ()
                {
@@ -1968,22 +1903,31 @@ namespace System.Windows.Forms
                        item_control.Visible = true;
                        item_control.Location = Point.Empty;
                        item_control.Width = ClientRectangle.Width;
+                       AdjustChildrenZOrder ();
 
                        int item_height = GetDetailsItemHeight ();
                        ItemSize = new Size (0, item_height); // We only cache Height for details view
                        int y = header_control.Height;
-#if NET_2_0
-                       bool using_groups = show_groups && groups.Count > 0 && view != View.List;
+                       layout_ht = y + (item_height * items.Count);
+                       if (items.Count > 0 && grid_lines) // some space for bottom gridline
+                               layout_ht += 2;
+
+                       bool using_groups = UsingGroups;
                        if (using_groups) {
+                               // Observe that this routines will override our layout_ht value
                                CalculateDetailsGroupItemsCount ();
                                CalculateGroupsLayout (ItemSize, 2, y);
                        }
-#endif
+
+                       if (virtual_mode) // no assgination on items is needed
+                               return;
 
                        for (int i = 0; i < items.Count; i++) {
                                ListViewItem item = items [i];
+
                                int display_index;
-#if NET_2_0
+                               int item_y;
+
                                if (using_groups) {
                                        ListViewGroup group = item.Group;
                                        if (group == null)
@@ -1993,42 +1937,41 @@ namespace System.Windows.Forms
                                        Point group_items_loc = group.items_area_location;
                                        display_index = group.starting_item + current_item;
 
-                                       y = current_item * (item_height + 2) + group_items_loc.Y;
-                                       SetItemLocation (display_index, 0, y, 0, 0);
+                                       y = item_y = current_item * (item_height + 2) + group_items_loc.Y;
+                                       SetItemLocation (display_index, 0, item_y, 0, 0);
                                        SetItemAtDisplayIndex (display_index, i);
-                                       item.SetPosition (new Point (0, y));
                                } else
-#endif
                                {
                                        display_index = i;
-                                       SetItemLocation (i, 0, y, 0, 0);
-#if NET_2_0                                    
-                                       item.SetPosition (new Point (0, y));
-#endif                                 
+                                       item_y = y;
+                                       SetItemLocation (i, 0, item_y, 0, 0);
                                        y += item_height;
                                }
-#if NET_2_0
-                               if (!virtual_mode) // Virtual mode sets Layout until draw time
-#endif
-                               {
-                                       item.Layout ();
-                                       item.DisplayIndex = display_index;
-                               }
 
+                               item.Layout ();
+                               item.DisplayIndex = display_index;
+                               item.SetPosition (new Point (0, item_y));
                        }
+               }
 
-                       // some space for bottom gridline
-                       if (items.Count > 0 && grid_lines)
-                               y += 2;
-
-#if NET_2_0
-                       if (!using_groups) // With groups it has been previously computed
-#endif
-                               layout_ht = y;
+               // Need to make sure HeaderControl is on top, and we can't simply use BringToFront since
+               // these controls are implicit, so we need to re-populate our collection.
+               void AdjustChildrenZOrder ()
+               {
+                       SuspendLayout ();
+                       Controls.ClearImplicit ();
+                       Controls.AddImplicit (header_control);
+                       Controls.AddImplicit (item_control);
+                       Controls.AddImplicit (h_scroll);
+                       Controls.AddImplicit (v_scroll);
+                       ResumeLayout ();
                }
 
                private void AdjustItemsPositionArray (int count)
                {
+                       // In virtual mode we compute the positions on the fly.
+                       if (virtual_mode)
+                               return;
                        if (items_location.Length >= count)
                                return;
 
@@ -2065,13 +2008,14 @@ namespace System.Windows.Forms
                                LayoutIcons (SmallIconItemSize, true, 
                                                ThemeEngine.Current.ListViewHorizontalSpacing, 2);
                                break;
-#if NET_2_0
                        case View.Tile:
+                               if (!Application.VisualStylesEnabled)
+                                       goto case View.LargeIcon;
+
                                LayoutIcons (TileItemSize, alignment == ListViewAlignment.Left, 
                                                ThemeEngine.Current.ListViewHorizontalSpacing,
                                                ThemeEngine.Current.ListViewVerticalSpacing);
                                break;
-#endif
                        }
 
                        CalculateScrollBars ();
@@ -2079,20 +2023,52 @@ namespace System.Windows.Forms
 
                internal Point GetItemLocation (int index)
                {
-                       Point loc = items_location [index];
+                       Point loc = Point.Empty;
+                       if (virtual_mode)
+                               loc = GetFixedItemLocation (index);
+                       else
+                               loc = items_location [index];
+
                        loc.X -= h_marker; // Adjust to scroll
                        loc.Y -= v_marker;
 
                        return loc;
                }
 
+               Point GetFixedItemLocation (int index)
+               {
+                       Point loc = Point.Empty;
+
+                       switch (view) {
+                               case View.LargeIcon:
+                               case View.SmallIcon:
+                                       loc.X = index % cols * (item_size.Width + x_spacing);
+                                       loc.Y = index / cols * (item_size.Height + y_spacing);
+                                       break;
+                               case View.List:
+                                       loc.X = index / rows * (item_size.Width + x_spacing);
+                                       loc.Y = index % rows * (item_size.Height + y_spacing);
+                                       break;
+                               case View.Details:
+                                       loc.Y = header_control.Height + (index * item_size.Height);
+                                       break;
+                       }
+
+                       return loc;
+               }
+
                internal int GetItemIndex (int display_index)
                {
+                       if (virtual_mode)
+                               return display_index; // no reordering in virtual mode.
                        return reordered_items_indices [display_index];
                }
 
                internal ListViewItem GetItemAtDisplayIndex (int display_index)
                {
+                       // in virtual mode there's no reordering at all.
+                       if (virtual_mode)
+                               return items [display_index];
                        return items [reordered_items_indices [display_index]];
                }
 
@@ -2186,6 +2162,9 @@ namespace System.Windows.Forms
                                return result;
                        }
 
+                       if (virtual_mode)
+                               return GetFixedAdjustedIndex (key);
+
                        ItemMatrixLocation item_matrix_location = items_matrix_location [FocusedItem.DisplayIndex];
                        int row = item_matrix_location.Row;
                        int col = item_matrix_location.Col;
@@ -2239,6 +2218,47 @@ namespace System.Windows.Forms
                        return items [adjusted_index].DisplayIndex;
                }
 
+               // Used for virtual mode, where items *cannot* be re-arranged
+               int GetFixedAdjustedIndex (Keys key)
+               {
+                       int result;
+
+                       switch (key) {
+                               case Keys.Left:
+                                       if (view == View.List)
+                                               result = focused_item_index - rows;
+                                       else
+                                               result = focused_item_index - 1;
+                                       break;
+                               case Keys.Right:
+                                       if (view == View.List)
+                                               result = focused_item_index + rows;
+                                       else
+                                               result = focused_item_index + 1;
+                                       break;
+                               case Keys.Up:
+                                       if (view != View.List)
+                                               result = focused_item_index - cols;
+                                       else
+                                               result = focused_item_index - 1;
+                                       break;
+                               case Keys.Down:
+                                       if (view != View.List)
+                                               result = focused_item_index + cols;
+                                       else
+                                               result = focused_item_index + 1;
+                                       break;
+                               default:
+                                       return -1;
+
+                       }
+
+                       if (result < 0 || result >= items.Count)
+                               result = focused_item_index;
+
+                       return result;
+               }
+
                ListViewItem selection_start;
 
                private bool SelectItems (ArrayList sel_items)
@@ -2422,9 +2442,7 @@ namespace System.Windows.Forms
                        bool hover_processed = false;
                        bool checking = false;
                        ListViewItem prev_hovered_item;
-#if NET_2_0
                        ListViewItem prev_tooltip_item;
-#endif
                        int clicks;
                        Point drag_begin = new Point (-1, -1);
                        internal int dragged_item_index = -1;
@@ -2527,12 +2545,8 @@ namespace System.Windows.Forms
                                        ArrayList result = new ArrayList ();
                                        for (int i = 0; i < owner.Items.Count; i++) {
                                                bool intersects;
-#if NET_2_0
                                                // Can't iterate over specific items properties in virtualmode
                                                if (owner.View == View.Details && !owner.FullRowSelect && !owner.VirtualMode)
-#else
-                                               if (owner.View == View.Details && !owner.FullRowSelect)
-#endif
                                                        intersects = BoxIntersectsText (i);
                                                else
                                                        intersects = BoxIntersectsItem (i);
@@ -2612,9 +2626,6 @@ namespace System.Windows.Forms
                                                // and if we are in 1.1 profile only take into account
                                                // double clicks
                                                if (owner.StateImageList != null && owner.StateImageList.Images.Count < 2 
-#if !NET_2_0
-                                                               && me.Clicks == 1
-#endif
                                                                )
                                                        return;
 
@@ -2631,7 +2642,7 @@ namespace System.Windows.Forms
                                        if (owner.View == View.Details) {
                                                bool over_text = item.TextBounds.Contains (pt);
                                                if (owner.FullRowSelect) {
-                                                       clicked_item = owner.items [i];
+                                                       clicked_item = item;
                                                        bool over_item_column = (me.X > owner.Columns[0].X && me.X < owner.Columns[0].X + owner.Columns[0].Width);
                                                        if (!over_text && over_item_column && owner.MultiSelect)
                                                                box_selecting = true;
@@ -2659,7 +2670,6 @@ namespace System.Windows.Forms
                                                clicked_item.Selected = true;
                                        }
 
-#if NET_2_0
                                        if (owner.VirtualMode && changed) {
                                                // Broken event - It's not fired from Item.Selected also
                                                ListViewVirtualItemsSelectionRangeChangedEventArgs args = 
@@ -2667,7 +2677,6 @@ namespace System.Windows.Forms
 
                                                owner.OnVirtualItemsSelectionRangeChanged (args);
                                        }
-#endif
                                        // Report clicks only if the item was clicked. On MS the
                                        // clicks are only raised if you click an item
                                        clicks = me.Clicks;
@@ -2678,6 +2687,9 @@ namespace System.Windows.Forms
                                                if (owner.LabelEdit && !changed)
                                                        BeginEdit (clicked_item); // this is probably not the correct place to execute BeginEdit
                                        }
+
+                                       drag_begin = me.Location;
+                                       dragged_item_index = clicked_item.Index;
                                } else {
                                        if (owner.MultiSelect)
                                                box_selecting = true;
@@ -2708,9 +2720,7 @@ namespace System.Windows.Forms
                                        return;
                                if ((me.Button != MouseButtons.Left && me.Button != MouseButtons.Right) &&
                                        !hover_processed && owner.Activation != ItemActivation.OneClick
-#if NET_2_0
                                        && !owner.ShowItemToolTips
-#endif
                                                )
                                        return;
 
@@ -2725,18 +2735,14 @@ namespace System.Windows.Forms
                                // Need to invalidate the item in HotTracking to show/hide the underline style
                                if (owner.Activation == ItemActivation.OneClick) {
                                        if (item == null && owner.HotItemIndex != -1) {
-#if NET_2_0
                                                if (owner.HotTracking)
                                                        Invalidate (owner.Items [owner.HotItemIndex].Bounds); // Previous one
-#endif
 
                                                Cursor = Cursors.Default;
                                                owner.HotItemIndex = -1;
                                        } else if (item != null && owner.HotItemIndex == -1) {
-#if NET_2_0
                                                if (owner.HotTracking)
                                                        Invalidate (item.Bounds);
-#endif
 
                                                Cursor = Cursors.Hand;
                                                owner.HotItemIndex = item.Index;
@@ -2744,13 +2750,7 @@ namespace System.Windows.Forms
                                }
 
                                if (me.Button == MouseButtons.Left || me.Button == MouseButtons.Right) {
-                                       if (drag_begin.X == -1 && drag_begin.Y == -1) {
-                                               if (item != null) {
-                                                       drag_begin = new Point (me.X, me.Y);
-                                                       dragged_item_index = item.Index;
-                                               }
-
-                                       } else {
+                                       if (drag_begin != new Point (-1, -1)) {
                                                Rectangle r = new Rectangle (drag_begin, SystemInformation.DragSize);
                                                if (!r.Contains (me.X, me.Y)) {
                                                        ListViewItem dragged_item  = owner.items [dragged_item_index];
@@ -2762,7 +2762,6 @@ namespace System.Windows.Forms
                                        }
                                }
 
-#if NET_2_0
                                if (owner.ShowItemToolTips) {
                                        if (item == null) {
                                                owner.item_tooltip.Active = false;
@@ -2773,7 +2772,6 @@ namespace System.Windows.Forms
                                                prev_tooltip_item = item;
                                        }
                                }
-#endif
 
                        }
 
@@ -2805,9 +2803,7 @@ namespace System.Windows.Forms
                                        Select (); // Make sure we have the focus, since MouseHover doesn't give it to us
                                }
 
-#if NET_2_0
                                owner.OnItemMouseHover (new ListViewItemMouseHoverEventArgs (item));
-#endif
                        }
 
                        void HandleClicks (MouseEventArgs me)
@@ -2815,17 +2811,11 @@ namespace System.Windows.Forms
                                // if the click is not on an item,
                                // clicks remains as 0
                                if (clicks > 1) {
-#if !NET_2_0
-                                       owner.OnDoubleClick (EventArgs.Empty);
-                               } else if (clicks == 1) {
-                                       owner.OnClick (EventArgs.Empty);
-#else
                                        owner.OnDoubleClick (EventArgs.Empty);
                                        owner.OnMouseDoubleClick (me);
                                } else if (clicks == 1) {
                                        owner.OnClick (EventArgs.Empty);
                                        owner.OnMouseClick (me);
-#endif
                                }
 
                                clicks = 0;
@@ -3280,11 +3270,12 @@ namespace System.Windows.Forms
                        case View.List:
                                Scroll (h_scroll, -ItemSize.Width * lines);
                                break;
-#if NET_2_0
                        case View.Tile:
+                               if (!Application.VisualStylesEnabled)
+                                       goto case View.LargeIcon;
+
                                Scroll (v_scroll, -(ItemSize.Height + ThemeEngine.Current.ListViewVerticalSpacing) * 2 * lines);
                                break;
-#endif
                        }
                }
 
@@ -3299,8 +3290,11 @@ namespace System.Windows.Forms
                                GetItemAtDisplayIndex (display_index).Focused = true;
                        else if (focused_item_index != -1 && focused_item_index < items.Count) // Previous focused item
                                GetItemAtDisplayIndex (focused_item_index).Focused = false;
-
                        focused_item_index = display_index;
+                       if (display_index == -1)
+                               OnUIAFocusedItemChanged ();
+                               // otherwise the event will have been fired
+                               // when the ListViewItem's Focused was set
                }
 
                private void HorizontalScroller (object sender, EventArgs e)
@@ -3350,6 +3344,7 @@ namespace System.Windows.Forms
                protected override void CreateHandle ()
                {
                        base.CreateHandle ();
+                       is_selection_available = true;
                        for (int i = 0; i < SelectedItems.Count; i++)
                                OnSelectedIndexChanged (EventArgs.Empty);
                }
@@ -3357,9 +3352,6 @@ namespace System.Windows.Forms
                protected override void Dispose (bool disposing)
                {
                        if (disposing) {
-                               h_scroll.Dispose ();
-                               v_scroll.Dispose ();
-                               
                                large_image_list = null;
                                small_image_list = null;
                                state_image_list = null;
@@ -3367,9 +3359,7 @@ namespace System.Windows.Forms
                                foreach (ColumnHeader col in columns)
                                        col.SetListView (null);
 
-#if NET_2_0
                                if (!virtual_mode) // In virtual mode we don't save the items
-#endif
                                        foreach (ListViewItem item in items)
                                                item.Owner = null;
                        }
@@ -3404,13 +3394,11 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-#if NET_2_0
                protected override void OnBackgroundImageChanged (EventArgs e)
                {
                        item_control.BackgroundImage = BackgroundImage;
                        base.OnBackgroundImageChanged (e);
                }
-#endif
 
                protected virtual void OnBeforeLabelEdit (LabelEditEventArgs e)
                {
@@ -3419,14 +3407,13 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-               protected virtual void OnColumnClick (ColumnClickEventArgs e)
+               protected internal virtual void OnColumnClick (ColumnClickEventArgs e)
                {
                        ColumnClickEventHandler eh = (ColumnClickEventHandler)(Events [ColumnClickEvent]);
                        if (eh != null)
                                eh (this, e);
                }
 
-#if NET_2_0
                protected internal virtual void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
                {
                        DrawListViewColumnHeaderEventHandler eh = (DrawListViewColumnHeaderEventHandler)(Events[DrawColumnHeaderEvent]);
@@ -3448,13 +3435,6 @@ namespace System.Windows.Forms
                                eh(this, e);
                }
 
-#else
-               protected override void OnEnabledChanged (EventArgs e)
-               {
-                       base.OnEnabledChanged (e);
-               }
-#endif
-
                protected override void OnFontChanged (EventArgs e)
                {
                        base.OnFontChanged (e);
@@ -3465,9 +3445,7 @@ namespace System.Windows.Forms
                {
                        base.OnHandleCreated (e);
                        CalculateListView (alignment);
-#if NET_2_0
                        if (!virtual_mode) // Sorting is not allowed in virtual mode
-#endif
                                Sort ();
                }
 
@@ -3490,14 +3468,12 @@ namespace System.Windows.Forms
                                eh (this, ice);
                }
 
-#if NET_2_0
                protected internal virtual void OnItemChecked (ItemCheckedEventArgs e)
                {
                        ItemCheckedEventHandler eh = (ItemCheckedEventHandler)(Events [ItemCheckedEvent]);
                        if (eh != null)
                                eh (this, e);
                }
-#endif
 
                protected virtual void OnItemDrag (ItemDragEventArgs e)
                {
@@ -3506,7 +3482,6 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-#if NET_2_0
                protected virtual void OnItemMouseHover (ListViewItemMouseHoverEventArgs e)
                {
                        ListViewItemMouseHoverEventHandler eh = (ListViewItemMouseHoverEventHandler)(Events [ItemMouseHoverEvent]);
@@ -3531,7 +3506,6 @@ namespace System.Windows.Forms
                {
                        base.OnParentChanged (e);
                }
-#endif
 
                protected virtual void OnSelectedIndexChanged (EventArgs e)
                {
@@ -3545,7 +3519,6 @@ namespace System.Windows.Forms
                        base.OnSystemColorsChanged (e);
                }
 
-#if NET_2_0
                protected internal virtual void OnCacheVirtualItems (CacheVirtualItemsEventArgs e)
                {
                        CacheVirtualItemsEventHandler eh = (CacheVirtualItemsEventHandler)Events [CacheVirtualItemsEvent];
@@ -3582,7 +3555,6 @@ namespace System.Windows.Forms
                        if (eh != null)
                                eh (this, e);
                }
-#endif
 
                protected void RealizeProperties ()
                {
@@ -3634,7 +3606,6 @@ namespace System.Windows.Forms
                                Redraw (true);
                }
 
-#if NET_2_0
                public void AutoResizeColumn (int columnIndex, ColumnHeaderAutoResizeStyle headerAutoResize)
                {
                        if (columnIndex < 0 || columnIndex >= columns.Count)
@@ -3650,7 +3621,6 @@ namespace System.Windows.Forms
                                col.AutoResize (headerAutoResize);
                        EndUpdate ();
                }
-#endif
 
                public void BeginUpdate ()
                {
@@ -3679,7 +3649,13 @@ namespace System.Windows.Forms
                                return;
 
                        Rectangle view_rect = item_control.ClientRectangle;
-                       Rectangle bounds = new Rectangle (GetItemLocation (index), ItemSize);
+                       // Avoid direct access to items in virtual mode, and use item bounds otherwise, since we could have reordered items
+                       Rectangle bounds = virtual_mode ? new Rectangle (GetItemLocation (index), ItemSize) : items [index].Bounds;
+
+                       if (view == View.Details && header_style != ColumnHeaderStyle.None) {
+                               view_rect.Y += header_control.Height;
+                               view_rect.Height -= header_control.Height;
+                       }
 
                        if (view_rect.Contains (bounds))
                                return;
@@ -3691,13 +3667,12 @@ namespace System.Windows.Forms
                                        h_scroll.Value += (bounds.Right - view_rect.Right);
                        }
 
-                       if (bounds.Top < 0)
-                               v_scroll.Value += bounds.Top;
+                       if (bounds.Top < view_rect.Y)
+                               v_scroll.Value += bounds.Top - view_rect.Y;
                        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)
@@ -3715,7 +3690,6 @@ namespace System.Windows.Forms
                {
                        return FindItemWithText (text, includeSubItemsInSearch, startIndex, isPrefixSearch, false);
                }
-#endif
                
                internal ListViewItem FindItemWithText (string text, bool includeSubItemsInSearch, int startIndex, bool isPrefixSearch, bool roundtrip)
                {
@@ -3725,7 +3699,6 @@ namespace System.Windows.Forms
                        if (text == null)
                                throw new ArgumentNullException ("text");
 
-#if NET_2_0
                        if (virtual_mode) {
                                SearchForVirtualItemEventArgs args = new SearchForVirtualItemEventArgs (true,
                                                isPrefixSearch, includeSubItemsInSearch, text, Point.Empty, 
@@ -3738,7 +3711,6 @@ namespace System.Windows.Forms
 
                                return null;
                        }
-#endif
 
                        int i = startIndex;
                        while (true) {
@@ -3780,7 +3752,6 @@ namespace System.Windows.Forms
                        return null;
                }
 
-#if NET_2_0
                public ListViewItem FindNearestItem (SearchDirectionHint searchDirection, int x, int y)
                {
                        return FindNearestItem (searchDirection, new Point (x, y));
@@ -3857,7 +3828,6 @@ namespace System.Windows.Forms
 
                        return item;
                }
-#endif
                
                public ListViewItem GetItemAt (int x, int y)
                {
@@ -3885,7 +3855,6 @@ namespace System.Windows.Forms
                        return items [index].GetBounds (portion);
                }
 
-#if NET_2_0
                public ListViewHitTestInfo HitTest (Point point)
                {
                        return HitTest (point.X, point.Y);
@@ -3940,14 +3909,11 @@ namespace System.Windows.Forms
                        if (!invalidateOnly)
                                Update ();
                }
-#endif
 
                public void Sort ()
                {
-#if NET_2_0
                        if (virtual_mode)
                                throw new InvalidOperationException ();
-#endif
 
                        Sort (true);
                }
@@ -4247,9 +4213,7 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class CheckedIndexCollection : IList, ICollection, IEnumerable
                {
                        private readonly ListView owner;
@@ -4383,9 +4347,7 @@ namespace System.Windows.Forms
                        }
                }       // CheckedIndexCollection
 
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class CheckedListViewItemCollection : IList, ICollection, IEnumerable
                {
                        private readonly ListView owner;
@@ -4416,10 +4378,8 @@ namespace System.Windows.Forms
 
                        public ListViewItem this [int index] {
                                get {
-#if NET_2_0
                                        if (owner.VirtualMode)
                                                throw new InvalidOperationException ();
-#endif
                                        ArrayList checked_items = List;
                                        if (index < 0 || index >= checked_items.Count)
                                                throw new ArgumentOutOfRangeException ("index");
@@ -4427,14 +4387,12 @@ namespace System.Windows.Forms
                                }
                        }
 
-#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; }
@@ -4462,19 +4420,15 @@ namespace System.Windows.Forms
                                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 NET_2_0
                                if (owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
                                if (!owner.CheckBoxes)
                                        return;
                                List.CopyTo (dest, index);
@@ -4482,10 +4436,8 @@ namespace System.Windows.Forms
 
                        public IEnumerator GetEnumerator ()
                        {
-#if NET_2_0
                                if (owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
                                if (!owner.CheckBoxes)
                                        return (new ListViewItem [0]).GetEnumerator ();
                                return List.GetEnumerator ();
@@ -4532,22 +4484,17 @@ namespace System.Windows.Forms
 
                        public int IndexOf (ListViewItem item)
                        {
-#if NET_2_0
                                if (owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
                                if (!owner.CheckBoxes)
                                        return -1;
                                return List.IndexOf (item);
                        }
 
-#if NET_2_0
                        public virtual int IndexOfKey (string key)
                        {
-#if NET_2_0
                                if (owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
                                if (key == null || key.Length == 0)
                                        return -1;
 
@@ -4560,7 +4507,6 @@ namespace System.Windows.Forms
 
                                return -1;
                        }
-#endif
                        #endregion      // Public Methods
 
                        internal ArrayList List {
@@ -4588,16 +4534,13 @@ namespace System.Windows.Forms
                        }
                }       // CheckedListViewItemCollection
 
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class ColumnHeaderCollection : IList, ICollection, IEnumerable
                {
                        internal ArrayList list;
                        private ListView owner;
 
                        #region UIA Framework Events 
-#if NET_2_0
                        //NOTE:
                        //      We are using Reflection to add/remove internal events.
                        //      Class ListViewProvider uses the events when View is Details.
@@ -4627,7 +4570,6 @@ namespace System.Windows.Forms
                                        eh (owner, args);
                        }
 
-#endif
                        #endregion UIA Framework Events 
 
                        #region Public Constructor
@@ -4656,7 +4598,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-#if NET_2_0
                        public virtual ColumnHeader this [string key] {
                                get {
                                        int idx = IndexOfKey (key);
@@ -4666,7 +4607,6 @@ namespace System.Windows.Forms
                                        return (ColumnHeader) list [idx];
                                }
                        }
-#endif
 
                        bool ICollection.IsSynchronized {
                                get { return true; }
@@ -4692,28 +4632,20 @@ namespace System.Windows.Forms
                                int idx = list.Add (value);
                                owner.AddColumn (value, idx, true);
 
-#if NET_2_0
                                //UIA Framework event: Item Added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, value));
-#endif
 
                                return idx;
                        }
 
-#if NET_2_0
                        public virtual ColumnHeader Add (string text, int width, HorizontalAlignment textAlign)
                        {
                                string str = text;
-#else
-                       public virtual ColumnHeader Add (string str, int width, HorizontalAlignment textAlign)
-                       {
-#endif
                                ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
                                this.Add (colHeader);
                                return colHeader;
                        }
 
-#if NET_2_0
                        public virtual ColumnHeader Add (string text)
                        {
                                return Add (String.Empty, text);
@@ -4753,7 +4685,6 @@ namespace System.Windows.Forms
                                Add (colHeader);
                                return colHeader;
                        }
-#endif
 
                        public virtual void AddRange (ColumnHeader [] values)
                        {
@@ -4772,10 +4703,8 @@ namespace System.Windows.Forms
                                list.Clear ();
                                owner.ReorderColumns (new int [0], true);
 
-#if NET_2_0
                                //UIA Framework event: Items cleared
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null));
-#endif
 
                        }
 
@@ -4784,12 +4713,10 @@ namespace System.Windows.Forms
                                return list.Contains (value);
                        }
 
-#if NET_2_0
                        public virtual bool ContainsKey (string key)
                        {
                                return IndexOfKey (key) != -1;
                        }
-#endif
 
                        public IEnumerator GetEnumerator ()
                        {
@@ -4851,7 +4778,6 @@ namespace System.Windows.Forms
                                return list.IndexOf (value);
                        }
 
-#if NET_2_0
                        public virtual int IndexOfKey (string key)
                        {
                                if (key == null || key.Length == 0)
@@ -4865,7 +4791,6 @@ namespace System.Windows.Forms
 
                                return -1;
                        }
-#endif
 
                        public void Insert (int index, ColumnHeader value)
                        {
@@ -4877,13 +4802,10 @@ namespace System.Windows.Forms
                                list.Insert (index, value);
                                owner.AddColumn (value, index, true);
 
-#if NET_2_0
                                //UIA Framework event: Item added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, value));
-#endif
                        }
 
-#if NET_2_0
                        public void Insert (int index, string text)
                        {
                                Insert (index, String.Empty, text);
@@ -4921,16 +4843,10 @@ namespace System.Windows.Forms
                                colHeader.ImageKey = imageKey;
                                Insert (index, colHeader);
                        }
-#endif
 
-#if NET_2_0
                        public void Insert (int index, string text, int width, HorizontalAlignment textAlign)
                        {
                                string str = text;
-#else
-                       public void Insert (int index, string str, int width, HorizontalAlignment textAlign)
-                       {
-#endif
                                ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
                                this.Insert (index, colHeader);
                        }
@@ -4958,20 +4874,16 @@ namespace System.Windows.Forms
                                column.InternalDisplayIndex = -1;
                                owner.ReorderColumns (display_indices, true);
 
-#if NET_2_0
                                //UIA Framework event: Item Removed
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, column));
-#endif
                        }
 
-#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)
                        {
@@ -4986,19 +4898,14 @@ namespace System.Windows.Forms
 
                }       // ColumnHeaderCollection
 
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class ListViewItemCollection : IList, ICollection, IEnumerable
                {
                        private readonly ArrayList list;
                        private ListView owner;
-#if NET_2_0
                        private ListViewGroup group;
-#endif
 
                        #region UIA Framework Events 
-#if NET_2_0
                        //NOTE:
                        //      We are using Reflection to add/remove internal events.
                        //      Class ListViewProvider uses the events.
@@ -5028,7 +4935,6 @@ namespace System.Windows.Forms
                                        eh (owner, args);
                        }
 
-#endif
                        #endregion UIA Framework Events 
 
                        // The collection can belong to a ListView (main) or to a ListViewGroup (sub-collection)
@@ -5043,22 +4949,18 @@ namespace System.Windows.Forms
                        }
                        #endregion      // Public Constructor
 
-#if NET_2_0
                        internal ListViewItemCollection (ListView owner, ListViewGroup group) : this (owner)
                        {
                                this.group = group;
                                is_main_collection = false;
                        }
-#endif
 
                        #region Public Properties
                        [Browsable (false)]
                        public int Count {
                                get {
-#if NET_2_0
                                        if (owner != null && owner.VirtualMode)
                                                return owner.VirtualListSize;
-#endif
 
                                        return list.Count; 
                                }
@@ -5068,38 +4970,22 @@ namespace System.Windows.Forms
                                get { return false; }
                        }
 
-#if NET_2_0
                        public virtual ListViewItem this [int index] {
-#else
-                       public virtual ListViewItem this [int displayIndex] {
-#endif
                                get {
-#if !NET_2_0
-                                       int index = displayIndex;
-#endif
-
                                        if (index < 0 || index >= Count)
                                                throw new ArgumentOutOfRangeException ("index");
 
-#if NET_2_0
                                        if (owner != null && owner.VirtualMode)
                                                return RetrieveVirtualItemFromOwner (index);
-#endif
                                        return (ListViewItem) list [index];
                                }
 
                                set {
-#if !NET_2_0
-                                       int index = displayIndex;
-#endif
-
                                        if (index < 0 || index >= Count)
                                                throw new ArgumentOutOfRangeException ("index");
 
-#if NET_2_0
                                        if (owner != null && owner.VirtualMode)
                                                throw new InvalidOperationException ();
-#endif
 
                                        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");
@@ -5109,33 +4995,26 @@ namespace System.Windows.Forms
 
                                        if (is_main_collection)
                                                value.Owner = owner;
-#if NET_2_0
                                        else {
                                                if (value.Group != null)
                                                        value.Group.Items.Remove (value);
 
                                                value.SetGroup (group);
                                        }
-#endif
 
-#if NET_2_0
                                        //UIA Framework event: Item Replaced
                                        OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, list [index]));
-#endif
 
                                        list [index] = value;
 
                                        CollectionChanged (true);
 
-#if NET_2_0
                                        //UIA Framework event: Item Replaced
                                        OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, value));
-#endif
 
                                }
                        }
 
-#if NET_2_0
                        public virtual ListViewItem this [string key] {
                                get {
                                        int idx = IndexOfKey (key);
@@ -5145,7 +5024,6 @@ namespace System.Windows.Forms
                                        return this [idx];
                                }
                        }
-#endif
 
                        bool ICollection.IsSynchronized {
                                get { return true; }
@@ -5162,10 +5040,8 @@ namespace System.Windows.Forms
                        object IList.this [int index] {
                                get { return this [index]; }
                                set {
-#if NET_2_0
                                        //UIA Framework event: Item Replaced
                                        OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, this [index]));
-#endif
 
                                        if (value is ListViewItem)
                                                this [index] = (ListViewItem) value;
@@ -5173,10 +5049,8 @@ namespace System.Windows.Forms
                                                this [index] = new ListViewItem (value.ToString ());
 
                                        OnChange ();
-#if NET_2_0
                                        //UIA Framework event: Item Replaced
                                        OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, value));
-#endif
                                }
                        }
                        #endregion      // Public Properties
@@ -5184,10 +5058,8 @@ namespace System.Windows.Forms
                        #region Public Methods
                        public virtual ListViewItem Add (ListViewItem value)
                        {
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                AddItem (value);
 
@@ -5195,10 +5067,8 @@ namespace System.Windows.Forms
                                if (is_main_collection || value.ListView != null)
                                        CollectionChanged (true);
 
-#if NET_2_0
                                //UIA Framework event: Item Added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, value));
-#endif
 
                                return value;
                        }
@@ -5215,7 +5085,6 @@ namespace System.Windows.Forms
                                return this.Add (item);
                        }
 
-#if NET_2_0
                        public virtual ListViewItem Add (string text, string imageKey)
                        {
                                ListViewItem item = new ListViewItem (text, imageKey);
@@ -5235,32 +5104,21 @@ namespace System.Windows.Forms
                                item.Name = key;
                                return this.Add (item);
                        }
-#endif
 
-#if NET_2_0
                        public void AddRange (ListViewItem [] items)
                        {
-#else
-                       public void AddRange (ListViewItem [] values)
-                       {
-                               ListViewItem [] items = values;
-#endif
                                if (items == null)
                                        throw new ArgumentNullException ("Argument cannot be null!", "items");
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                owner.BeginUpdate ();
                                
                                foreach (ListViewItem item in items) {
                                        AddItem (item);
 
-#if NET_2_0
                                        //UIA Framework event: Item Added
                                        OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, item));
-#endif
                                }
 
                                owner.EndUpdate ();
@@ -5268,7 +5126,6 @@ namespace System.Windows.Forms
                                CollectionChanged (true);
                        }
 
-#if NET_2_0
                        public void AddRange (ListViewItemCollection items)
                        {
                                if (items == null)
@@ -5278,58 +5135,72 @@ namespace System.Windows.Forms
                                items.CopyTo (itemArray,0);
                                this.AddRange (itemArray);
                        }
-#endif
 
                        public virtual void Clear ()
                        {
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
                                if (is_main_collection && owner != null) {
                                        owner.SetFocusedItem (-1);
                                        owner.h_scroll.Value = owner.v_scroll.Value = 0;
-                                               
+
+                                       // first remove any item in the groups that *are* part of this LV too
+                                       foreach (ListViewGroup group in owner.groups)
+                                               group.Items.ClearItemsWithSameListView ();
+                               
                                        foreach (ListViewItem item in list) {
                                                owner.item_control.CancelEdit (item);
                                                item.Owner = null;
                                        }
-                                       
                                }
-#if NET_2_0
                                else
                                        foreach (ListViewItem item in list)
                                                item.SetGroup (null);
-#endif
 
                                list.Clear ();
                                CollectionChanged (false);
 
-#if NET_2_0
                                //UIA Framework event: Items Removed
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null));
-#endif
 
                        }
 
+                       // This method is intended to be used from ListViewGroup.Items, not from ListView.Items,
+                       // added for performance reasons (avoid calling manually Remove for every item on ListViewGroup.Items)
+                       void ClearItemsWithSameListView ()
+                       {
+                               if (is_main_collection)
+                                       return;
+
+                               int counter = list.Count - 1;
+                               while (counter >= 0) {
+                                       ListViewItem item = list [counter] as ListViewItem;
+
+                                       // remove only if the items in group have being added to the ListView too
+                                       if (item.ListView == group.ListView) {
+                                               list.RemoveAt (counter);
+                                               item.SetGroup (null);
+                                       }
+                                               
+                                       counter--;
+                               }
+                       }
+
                        public bool Contains (ListViewItem item)
                        {
                                return IndexOf (item) != -1;
                        }
 
-#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)
@@ -5348,14 +5219,11 @@ namespace System.Windows.Forms
 
                                return retval;
                        }
-#endif
 
                        public IEnumerator GetEnumerator ()
                        {
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                // This enumerator makes a copy of the collection so
                                // it can be deleted from in a foreach
@@ -5367,10 +5235,8 @@ namespace System.Windows.Forms
                                int result;
                                ListViewItem li;
 
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                if (item is ListViewItem) {
                                        li = (ListViewItem) item;
@@ -5389,10 +5255,8 @@ namespace System.Windows.Forms
                                result = list.Add (li);
                                CollectionChanged (true);
 
-#if NET_2_0
                                //UIA Framework event: Item Added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, li));
-#endif
 
                                return result;
                        }
@@ -5414,10 +5278,8 @@ namespace System.Windows.Forms
                                else
                                        this.Insert (index, item.ToString ());
 
-#if NET_2_0
                                //UIA Framework event: Item Added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, this [index]));
-#endif
                        }
 
                        void IList.Remove (object item)
@@ -5427,7 +5289,6 @@ namespace System.Windows.Forms
 
                        public int IndexOf (ListViewItem item)
                        {
-#if NET_2_0
                                if (owner != null && owner.VirtualMode) {
                                        for (int i = 0; i < Count; i++)
                                                if (RetrieveVirtualItemFromOwner (i) == item)
@@ -5435,12 +5296,10 @@ namespace System.Windows.Forms
 
                                        return -1;
                                }
-#endif
                                
                                return list.IndexOf (item);
                        }
 
-#if NET_2_0
                        public virtual int IndexOfKey (string key)
                        {
                                if (key == null || key.Length == 0)
@@ -5454,17 +5313,14 @@ namespace System.Windows.Forms
 
                                return -1;
                        }
-#endif
 
                        public ListViewItem Insert (int index, ListViewItem item)
                        {
                                if (index < 0 || index > list.Count)
                                        throw new ArgumentOutOfRangeException ("index");
 
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                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");
@@ -5474,24 +5330,23 @@ namespace System.Windows.Forms
 
                                if (is_main_collection)
                                        item.Owner = owner;
-#if NET_2_0
                                else {
                                        if (item.Group != null)
                                                item.Group.Items.Remove (item);
 
                                        item.SetGroup (group);
                                }
-#endif
 
                                list.Insert (index, item);
 
                                if (is_main_collection || item.ListView != null)
                                        CollectionChanged (true);
 
-#if NET_2_0
+                               // force an update of the selected info if the new item is selected.
+                               if (item.Selected)
+                                       item.SetSelectedCore (true);
                                //UIA Framework event: Item Added
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, item));
-#endif
 
                                return item;
                        }
@@ -5506,7 +5361,6 @@ namespace System.Windows.Forms
                                return this.Insert (index, new ListViewItem (text, imageIndex));
                        }
 
-#if NET_2_0
                        public ListViewItem Insert (int index, string text, string imageKey)
                        {
                                ListViewItem lvi = new ListViewItem (text, imageKey);
@@ -5526,14 +5380,11 @@ namespace System.Windows.Forms
                                lvi.Name = key;
                                return Insert (index, lvi);
                        }
-#endif
 
                        public virtual void Remove (ListViewItem item)
                        {
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                int idx = list.IndexOf (item);
                                if (idx != -1)
@@ -5545,10 +5396,8 @@ namespace System.Windows.Forms
                                if (index < 0 || index >= Count)
                                        throw new ArgumentOutOfRangeException ("index");
 
-#if NET_2_0
                                if (owner != null && owner.VirtualMode)
                                        throw new InvalidOperationException ();
-#endif
 
                                ListViewItem item = (ListViewItem) list [index];
 
@@ -5565,36 +5414,28 @@ namespace System.Windows.Forms
 
                                list.RemoveAt (index);
 
-#if NET_2_0
                                if (is_main_collection) {
                                        item.Owner = null;
                                        if (item.Group != null)
                                                item.Group.Items.Remove (item);
                                } else
                                        item.SetGroup (null);
-#else
-                               item.Owner = null;
-#endif
 
                                CollectionChanged (false);
                                if (selection_changed && owner != null)
                                        owner.OnSelectedIndexChanged (EventArgs.Empty);
 
 
-#if NET_2_0
                                //UIA Framework event: Item Removed 
                                OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, item));
-#endif
                        }
 
-#if NET_2_0
                        public virtual void RemoveByKey (string key)
                        {
                                int idx = IndexOfKey (key);
                                if (idx != -1)
                                        RemoveAt (idx);
                        }
-#endif
 
                        #endregion      // Public Methods
 
@@ -5607,7 +5448,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-#if NET_2_0
                        internal ListViewGroup Group {
                                get {
                                        return group;
@@ -5616,7 +5456,6 @@ namespace System.Windows.Forms
                                        group = value;
                                }
                        }
-#endif
 
                        void AddItem (ListViewItem value)
                        {
@@ -5627,17 +5466,18 @@ namespace System.Windows.Forms
                                        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");
                                if (is_main_collection)
                                        value.Owner = owner;
-#if NET_2_0
                                else {
                                        if (value.Group != null)
                                                value.Group.Items.Remove (value);
 
                                        value.SetGroup (group);
                                }
-#endif
 
                                list.Add (value);
 
+                               // force an update of the selected info if the new item is selected.
+                               if (value.Selected)
+                                       value.SetSelectedCore (true);
                        }
 
                        void CollectionChanged (bool sort)
@@ -5651,7 +5491,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-#if NET_2_0
                        ListViewItem RetrieveVirtualItemFromOwner (int displayIndex)
                        {
                                RetrieveVirtualItemEventArgs args = new RetrieveVirtualItemEventArgs (displayIndex);
@@ -5660,10 +5499,10 @@ namespace System.Windows.Forms
                                ListViewItem retval = args.Item;
                                retval.Owner = owner;
                                retval.DisplayIndex = displayIndex;
+                               retval.Layout ();
 
                                return retval;
                        }
-#endif
 
                        internal event CollectionChangedHandler Changed;
 
@@ -5686,9 +5525,7 @@ namespace System.Windows.Forms
                //
                // In virtual mode, SelectedIndexCollection directly saves the selection
                // information, instead of getting it from Items, making List read-and-write
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class SelectedIndexCollection : IList, ICollection, IEnumerable
                {
                        private readonly ListView owner;
@@ -5706,7 +5543,7 @@ namespace System.Windows.Forms
                        [Browsable (false)]
                        public int Count {
                                get {
-                                       if (!owner.IsHandleCreated)
+                                       if (!owner.is_selection_available)
                                                return 0;
 
                                        return List.Count;
@@ -5715,17 +5552,13 @@ namespace System.Windows.Forms
 
                        public bool IsReadOnly {
                                get { 
-#if NET_2_0
                                        return false;
-#else
-                                       return true; 
-#endif
                                }
                        }
 
                        public int this [int index] {
                                get {
-                                       if (!owner.IsHandleCreated || index < 0 || index >= List.Count)
+                                       if (!owner.is_selection_available || index < 0 || index >= List.Count)
                                                throw new ArgumentOutOfRangeException ("index");
 
                                        return (int) List [index];
@@ -5742,11 +5575,7 @@ namespace System.Windows.Forms
 
                        bool IList.IsFixedSize {
                                get { 
-#if NET_2_0
                                        return false;
-#else
-                                       return true;
-#endif
                                }
                        }
 
@@ -5757,32 +5586,25 @@ namespace System.Windows.Forms
                        #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");
 
-                               if (owner.virtual_mode && !owner.IsHandleCreated)
+                               if (owner.virtual_mode && !owner.is_selection_available)
                                        return -1;
 
                                owner.Items [itemIndex].Selected = true;
 
-                               if (!owner.IsHandleCreated)
+                               if (!owner.is_selection_available)
                                        return 0;
 
                                return List.Count;
                        }
-#endif
 
-#if NET_2_0
-                       public 
-#else
-                       internal
-#endif 
-                       void Clear ()
+                       public void Clear ()
                        {
-                               if (!owner.IsHandleCreated)
+                               if (!owner.is_selection_available)
                                        return;
 
                                int [] indexes = (int []) List.ToArray (typeof (int));
@@ -5846,13 +5668,12 @@ namespace System.Windows.Forms
 
                        public int IndexOf (int selectedIndex)
                        {
-                               if (!owner.IsHandleCreated)
+                               if (!owner.is_selection_available)
                                        return -1;
 
                                return List.IndexOf (selectedIndex);
                        }
 
-#if NET_2_0
                        public void Remove (int itemIndex)
                        {
                                if (itemIndex < 0 || itemIndex >= owner.Items.Count)
@@ -5860,16 +5681,13 @@ namespace System.Windows.Forms
 
                                owner.Items [itemIndex].Selected = false;
                        }
-#endif
                        #endregion      // Public Methods
 
                        internal ArrayList List {
                                get {
                                        if (list == null) {
                                                list = new ArrayList ();
-#if NET_2_0
                                                if (!owner.VirtualMode)
-#endif
                                                for (int i = 0; i < owner.Items.Count; i++) {
                                                        if (owner.Items [i].Selected)
                                                                list.Add (i);
@@ -5890,7 +5708,6 @@ namespace System.Windows.Forms
                                Reset ();
                        }
 
-#if NET_2_0
                        internal void RemoveIndex (int index)
                        {
                                int idx = List.BinarySearch (index);
@@ -5918,13 +5735,10 @@ namespace System.Windows.Forms
 
                                List.Insert (iMin, index);
                        }
-#endif
 
                }       // SelectedIndexCollection
 
-#if NET_2_0
                [ListBindable (false)]
-#endif
                public class SelectedListViewItemCollection : IList, ICollection, IEnumerable
                {
                        private readonly ListView owner;
@@ -5950,7 +5764,7 @@ namespace System.Windows.Forms
 
                        public ListViewItem this [int index] {
                                get {
-                                       if (!owner.IsHandleCreated || index < 0 || index >= Count)
+                                       if (!owner.is_selection_available || index < 0 || index >= Count)
                                                throw new ArgumentOutOfRangeException ("index");
 
                                        int item_index = owner.SelectedIndices [index];
@@ -5958,7 +5772,6 @@ namespace System.Windows.Forms
                                }
                        }
 
-#if NET_2_0
                        public virtual ListViewItem this [string key] {
                                get {
                                        int idx = IndexOfKey (key);
@@ -5968,7 +5781,6 @@ namespace System.Windows.Forms
                                        return this [idx];
                                }
                        }
-#endif
 
                        bool ICollection.IsSynchronized {
                                get { return false; }
@@ -5999,16 +5811,14 @@ namespace System.Windows.Forms
                                return IndexOf (item) != -1;
                        }
 
-#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)
+                               if (!owner.is_selection_available)
                                        return;
                                if (index > Count) // Throws ArgumentException instead of IOOR exception
                                        throw new ArgumentException ("index");
@@ -6019,7 +5829,7 @@ namespace System.Windows.Forms
 
                        public IEnumerator GetEnumerator ()
                        {
-                               if (!owner.IsHandleCreated)
+                               if (!owner.is_selection_available)
                                        return (new ListViewItem [0]).GetEnumerator ();
 
                                ListViewItem [] items = new ListViewItem [Count];
@@ -6065,7 +5875,7 @@ namespace System.Windows.Forms
 
                        public int IndexOf (ListViewItem item)
                        {
-                               if (!owner.IsHandleCreated)
+                               if (!owner.is_selection_available)
                                        return -1;
 
                                for (int i = 0; i < Count; i++)
@@ -6075,10 +5885,9 @@ namespace System.Windows.Forms
                                return -1;
                        }
 
-#if NET_2_0
                        public virtual int IndexOfKey (string key)
                        {
-                               if (!owner.IsHandleCreated || key == null || key.Length == 0)
+                               if (!owner.is_selection_available || key == null || key.Length == 0)
                                        return -1;
 
                                for (int i = 0; i < Count; i++) {
@@ -6089,7 +5898,6 @@ namespace System.Windows.Forms
 
                                return -1;
                        }
-#endif
                        #endregion      // Public Methods
 
                }       // SelectedListViewItemCollection
@@ -6129,7 +5937,6 @@ namespace System.Windows.Forms
                }
 
                #endregion // Subclasses
-#if NET_2_0
                protected override void OnResize (EventArgs e)
                {
                        base.OnResize (e);
@@ -6209,21 +6016,13 @@ namespace System.Windows.Forms
                        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)
+               internal void RaiseColumnWidthChanged (ColumnHeader column)
                {
+                       int index = Columns.IndexOf (column);
+                       RaiseColumnWidthChanged (index);
                }
-#endif
 
-#if NET_2_0
                
                #region UIA Framework: Methods, Properties and Events
                
@@ -6232,6 +6031,7 @@ namespace System.Windows.Forms
                static object UIAMultiSelectChangedEvent = new object ();
                static object UIAViewChangedEvent = new object ();
                static object UIACheckBoxesChangedEvent = new object ();
+               static object UIAFocusedItemChangedEvent = new object ();
 
                internal Rectangle UIAHeaderControl {
                        get { return header_control.Bounds; }
@@ -6283,11 +6083,21 @@ namespace System.Windows.Forms
                        remove { Events.RemoveHandler (UIAViewChangedEvent, value); }
                }
 
+               internal event EventHandler UIAFocusedItemChanged {
+                       add { Events.AddHandler (UIAFocusedItemChangedEvent, value); }
+                       remove { Events.RemoveHandler (UIAFocusedItemChangedEvent, value); }
+               }
+
                internal Rectangle UIAGetHeaderBounds (ListViewGroup group)
                {
                        return group.HeaderBounds;
                }
 
+               internal int UIAItemsLocationLength
+               {
+                       get { return items_location.Length; }
+               }
+
                private void OnUIACheckBoxesChanged ()
                {
                        EventHandler eh = (EventHandler) Events [UIACheckBoxesChangedEvent];
@@ -6323,8 +6133,14 @@ namespace System.Windows.Forms
                                eh (this, EventArgs.Empty);
                }
 
+               internal void OnUIAFocusedItemChanged ()
+               {
+                       EventHandler eh = (EventHandler) Events [UIAFocusedItemChangedEvent];
+                       if (eh != null)
+                               eh (this, EventArgs.Empty);
+               }
+
                #endregion // UIA Framework: Methods, Properties and Events
 
-#endif
        }
 }