- Same goes for setting the image size. Just resize them all
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGrid.cs
index 44b03d1a79c710445494efa24bf6c4829421b36e..932e81686d4577a3a178d8d2e5dde466f9e9bbc2 100644 (file)
@@ -67,8 +67,8 @@ namespace System.Windows.Forms
                        #region Private Constructors
                        internal HitTestInfo ()
                        {
-                               column = 0;
-                               row = 0;
+                               column = -1;
+                               row = -1;
                                type =  HitTestType.None;
                        }
                        #endregion
@@ -103,7 +103,7 @@ namespace System.Windows.Forms
 
                        public override string ToString ()
                        {
-                               return base.ToString ();
+                               return "{ " + type + "," + row + "," + column + "}";
                        }
 
                }
@@ -123,12 +123,13 @@ namespace System.Windows.Forms
                private static readonly Color   def_selection_backcolor = ThemeEngine.Current.DataGridSelectionBackColor;
                private static readonly Color   def_selection_forecolor = ThemeEngine.Current.DataGridSelectionForeColor;
                private static readonly Color   def_link_color = ThemeEngine.Current.DataGridLinkColor;
+               internal readonly int def_preferredrow_height;
 
                private bool allow_navigation;
                private bool allow_sorting;
                private Color alternating_backcolor;
+               private Color backColor;
                private Color background_color;
-               internal BorderStyle border_style;
                private Color caption_backcolor;
                private Font caption_font;
                private Color caption_forecolor;
@@ -149,7 +150,7 @@ namespace System.Windows.Forms
                private Color link_hovercolor;
                private Color parentrowsback_color;
                private Color parentrowsfore_color;
-               internal bool parentrows_visible;
+               private bool parentrows_visible;
                private int preferredcolumn_width;
                private int preferredrow_height;
                private bool _readonly;
@@ -160,12 +161,9 @@ namespace System.Windows.Forms
                internal int visiblecolumn_count;
                internal int visiblerow_count;
                internal int first_visiblecolumn;
-               private int currentrow_index;
                private GridTableStylesCollection styles_collection;
                private DataGridParentRowsLabelStyle parentrowslabel_style;
                internal DataGridCell current_cell;
-               private Color forecolor;
-               private Color backcolor;
                private DataGridTableStyle default_style;
                private DataGridTableStyle current_style;
                internal HScrollBar horiz_scrollbar;
@@ -175,13 +173,24 @@ namespace System.Windows.Forms
                internal int horz_pixeloffset;
                internal bool is_editing;       // Current cell is edit mode
                internal bool is_changing;      // Indicates if current cell is been changed (in edit mode)
+               internal bool is_adding;        // Indicates when we are adding a row
+               private Hashtable selected_rows;
+               private bool ctrl_pressed;
+               private bool shift_pressed;
+               private bool begininit;
+               private CurrencyManager cached_currencymgr;
+               private CurrencyManager cached_currencymgr_events;
+               private bool accept_listmgrevents;
                #endregion // Local Variables
 
                #region Public Constructors
                public DataGrid ()
                {
+                       grid_drawing = new DataGridDrawing (this);
                        allow_navigation = true;
                        allow_sorting = true;
+                       begininit = false;
+                       backColor = ThemeEngine.Current.DataGridBackColor;
                        alternating_backcolor = def_alternating_backcolor;
                        background_color = def_background_color;
                        border_style = BorderStyle.Fixed3D;
@@ -205,10 +214,9 @@ namespace System.Windows.Forms
                        link_hovercolor = def_link_hovercolor;
                        parentrowsback_color = def_parentrowsback_color;
                        parentrowsfore_color = def_parentrowsfore_color;
-                       parentrows_visible = false; // should be true (temp)
+                       parentrows_visible = true;
                        preferredcolumn_width = ThemeEngine.Current.DataGridPreferredColumnWidth;
-                       preferredrow_height = 16;
-                       _readonly = false ;
+                       _readonly = false;
                        rowheaders_visible = true;
                        selection_backcolor = def_selection_backcolor;
                        selection_forecolor = def_selection_forecolor;
@@ -216,15 +224,19 @@ namespace System.Windows.Forms
                        visiblecolumn_count = 0;
                        visiblerow_count = 0;
                        current_cell = new DataGridCell ();
-                       currentrow_index = -1;
                        first_visiblerow = 0;
                        first_visiblecolumn = 0;
                        horz_pixeloffset = 0;
                        is_editing = false;
                        is_changing = false;
-                       forecolor = SystemColors.WindowText;
+                       is_adding = false;
                        parentrowslabel_style = DataGridParentRowsLabelStyle.Both;
-                       backcolor = SystemColors.Window;
+                       selected_rows = new Hashtable ();
+                       ctrl_pressed = false;
+                       shift_pressed = false;
+                       preferredrow_height = def_preferredrow_height = FontHeight + 3;
+                       cached_currencymgr_events = cached_currencymgr = null;
+                       accept_listmgrevents = true;
 
                        default_style = new DataGridTableStyle (true);
                        styles_collection = new GridTableStylesCollection (this);
@@ -235,10 +247,10 @@ namespace System.Windows.Forms
                        horiz_scrollbar = new HScrollBar ();
                        horiz_scrollbar.Scroll += new ScrollEventHandler  (GridHScrolled);
                        vert_scrollbar = new VScrollBar ();
-                       vert_scrollbar.Scroll += new ScrollEventHandler (GridVScrolled);
-                       grid_drawing = new DataGridDrawing (this);
+                       vert_scrollbar.Scroll += new ScrollEventHandler (GridVScrolled);                        
+                       KeyUp += new KeyEventHandler (OnKeyUpDG);                       
 
-                       SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
+                       SetStyle (ControlStyles.UserMouse, true);
 
                }
 
@@ -288,13 +300,10 @@ namespace System.Windows.Forms
 
                public Color BackColor {
                        get {
-                               return backcolor;
+                               return backColor;
                        }
                        set {
-                               if (backcolor != value) {
-                                       backcolor = value;
-                                       Refresh ();
-                               }
+                               backColor = value;
                        }
                }
 
@@ -326,17 +335,11 @@ namespace System.Windows.Forms
                [DispId(-504)]
                [DefaultValue(BorderStyle.Fixed3D)]
                public BorderStyle BorderStyle {
-                       get {
-                               return border_style;
-                       }
-
-                       set {
-                                if (border_style != value) {
-                                       border_style = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       OnBorderStyleChanged (EventArgs.Empty);
-                                       Refresh ();
-                               }
+                       get { return InternalBorderStyle; }
+                       set { 
+                               InternalBorderStyle = value; 
+                               CalcAreasAndInvalidate ();
+                               OnBorderStyleChanged (EventArgs.Empty);
                        }
                }
 
@@ -370,8 +373,7 @@ namespace System.Windows.Forms
                                }
 
                                caption_font = value;
-                               grid_drawing.CalcGridAreas ();
-                               Refresh ();
+                               CalcAreasAndInvalidate ();
                        }
                }
 
@@ -412,8 +414,7 @@ namespace System.Windows.Forms
                        set {
                                if (caption_visible != value) {
                                        caption_visible = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                        OnCaptionVisibleChanged (EventArgs.Empty);
                                }
                        }
@@ -428,8 +429,7 @@ namespace System.Windows.Forms
                        set {
                                if (columnheaders_visible != value) {
                                        columnheaders_visible = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -443,9 +443,33 @@ namespace System.Windows.Forms
 
                        set {
                                if (!current_cell.Equals (value)) {
-                                       grid_drawing.InvalidateRowHeader (current_cell.RowNumber); // old row header
-                                       current_cell = value;
+                                       CancelEditing ();
+                                       
+                                       int old_row = current_cell.RowNumber;
+                                       
+                                       if (value.RowNumber >= RowsCount) {
+                                               value.RowNumber = RowsCount == 0 ? 0 : RowsCount - 1;
+                                       }
+                                       
+                                       if (value.ColumnNumber >= CurrentTableStyle.GridColumnStyles.Count) {
+                                               value.ColumnNumber = CurrentTableStyle.GridColumnStyles.Count == 0 ? 0: CurrentTableStyle.GridColumnStyles.Count - 1;
+                                       }
+                                       
+                                       EnsureCellVisilibility (value);
+                                       current_cell = value;                                   
+                                       
+                                       if (current_cell.RowNumber != old_row) {
+                                               grid_drawing.InvalidateRowHeader (old_row);
+                                       }
+                                       
+                                       accept_listmgrevents = false;
+
+                                       if (cached_currencymgr_events !=  null) {
+                                               cached_currencymgr_events.Position = current_cell.RowNumber;
+                                       }
+                                       accept_listmgrevents = true;
                                        InvalidateCurrentRowHeader ();
+                                       OnCurrentCellChanged (EventArgs.Empty);
                                }
                        }
                }
@@ -454,13 +478,16 @@ namespace System.Windows.Forms
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                public int CurrentRowIndex {
                        get {
-                               return currentrow_index;
+                               if (ListManager == null) {
+                                       return -1;
+                               }
+                               
+                               return current_cell.RowNumber;
                        }
 
                        set {
-                               if (currentrow_index != value) {
-                                       currentrow_index = value;
-                                       Refresh ();
+                               if (current_cell.RowNumber != value) {
+                                       CurrentCell = new DataGridCell (value, current_cell.ColumnNumber);
                                }
                        }
                }
@@ -477,20 +504,27 @@ namespace System.Windows.Forms
                }
 
                [DefaultValue(null)]
-               [Editor ("System.Windows.Forms.Design.DataMemberListEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+               [Editor ("System.Windows.Forms.Design.DataMemberListEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                public string DataMember {
                        get { return datamember; }
                        set {
-                               if (SetDataMember (value)) {
-                                       SetNewDataSource ();
-                                       Refresh ();
+                               if (SetDataMember (value)) {                                    
+                                       SetDataSource (datasource);
+                                       if (styles_collection.Contains (value) == true) {
+                                               CurrentTableStyle = styles_collection[value];
+                                               current_style.CreateColumnsForTable (true);
+                                       } else {
+                                               CurrentTableStyle = default_style;
+                                               current_style.GridColumnStyles.Clear ();
+                                               current_style.CreateColumnsForTable (false);
+                                       }                                       
                                }
                        }
                }
 
                [DefaultValue(null)]
                [RefreshProperties(RefreshProperties.Repaint)]
-               [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+               [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
                public object DataSource {
                        get {
                                return datasource;
@@ -498,8 +532,7 @@ namespace System.Windows.Forms
 
                        set {
                                if (SetDataSource (value)) {
-                                       SetNewDataSource ();
-                                       Refresh ();
+                                       SetNewDataSource ();                                    
                                }
                        }
                }
@@ -534,15 +567,11 @@ namespace System.Windows.Forms
 
                public Color ForeColor {
                        get {
-                               return forecolor;
+                               return base.ForeColor;
                        }
 
                        set {
-                               if (forecolor != value) {
-                                       forecolor = value;
-                                       OnForeColorChanged (EventArgs.Empty);
-                                       Refresh ();
-                               }
+                               base.ForeColor = value;
                        }
                }
 
@@ -553,7 +582,7 @@ namespace System.Windows.Forms
 
                        set {
                                if (value == Color.Empty) {
-                                       throw new ArgumentNullException ("Color.Empty value is invalid.");
+                                       throw new ArgumentException ("Color.Empty value is invalid.");
                                }
 
                                if (gridline_color != value) {
@@ -584,7 +613,7 @@ namespace System.Windows.Forms
 
                        set {
                                if (value == Color.Empty) {
-                                       throw new ArgumentNullException ("Color.Empty value is invalid.");
+                                       throw new ArgumentException ("Color.Empty value is invalid.");
                                }
 
                                if (header_backcolor != value) {
@@ -602,7 +631,7 @@ namespace System.Windows.Forms
                        set {
                                if (header_font != null && !header_font.Equals (value)) {
                                        header_font = value;
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -628,21 +657,23 @@ namespace System.Windows.Forms
 
                public object this [DataGridCell cell] {
                        get  {
-                               throw new NotImplementedException ();
+                               return this [cell.RowNumber, cell.ColumnNumber];
                        }
 
                        set {
-                               throw new NotImplementedException ();
+                               this [cell.RowNumber, cell.ColumnNumber] = value;
                        }
                }
 
                public object this [int rowIndex, int columnIndex] {
                        get  {
-                               throw new NotImplementedException ();
+                               return CurrentTableStyle.GridColumnStyles[columnIndex].GetColumnValueAtRow (ListManager,
+                                       rowIndex);
                        }
 
                        set {
-                               throw new NotImplementedException ();
+                               CurrentTableStyle.GridColumnStyles[columnIndex].SetColumnValueAtRow (ListManager,
+                                       rowIndex, value);
                        }
                }
 
@@ -682,7 +713,16 @@ namespace System.Windows.Forms
                                        return null;
                                }
 
-                               return (CurrencyManager) BindingContext [real_datasource, DataMember];
+                               if (cached_currencymgr != null) {
+                                       return cached_currencymgr;
+                               }
+
+                               // If we bind real_datasource object we do not get the events from ListManger
+                               // since the object is not the datasource and does not match
+                               cached_currencymgr = (CurrencyManager) BindingContext [real_datasource, DataMember];
+                               cached_currencymgr_events = (CurrencyManager) BindingContext [datasource, DataMember];
+                               ConnectListManagerEvents ();
+                               return cached_currencymgr;
                        }
 
                        set {
@@ -748,8 +788,7 @@ namespace System.Windows.Forms
                        set {
                                if (parentrows_visible != value) {
                                        parentrows_visible = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                        OnParentRowsVisibleChanged (EventArgs.Empty);
                                }
                        }
@@ -783,8 +822,7 @@ namespace System.Windows.Forms
                        set {
                                if (preferredrow_height != value) {
                                        preferredrow_height = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -799,7 +837,7 @@ namespace System.Windows.Forms
                                if (_readonly != value) {
                                        _readonly = value;
                                        OnReadOnlyChanged (EventArgs.Empty);
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -813,8 +851,7 @@ namespace System.Windows.Forms
                        set {
                                if (rowheaders_visible != value) {
                                        rowheaders_visible = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -828,8 +865,7 @@ namespace System.Windows.Forms
                        set {
                                if (rowheaders_width != value) {
                                        rowheaders_width = value;
-                                       grid_drawing.CalcGridAreas ();
-                                       Refresh ();
+                                       CalcAreasAndInvalidate ();
                                }
                        }
                }
@@ -920,6 +956,8 @@ namespace System.Windows.Forms
                        }
                        set {
                                current_style = value;
+                               current_style.DataGrid = this;
+                               CalcAreasAndInvalidate ();
                        }
                }
 
@@ -927,11 +965,11 @@ namespace System.Windows.Forms
                        get { return first_visiblerow; }
                        set { first_visiblerow = value;}
                }
-
+               
                internal int RowsCount {
-                       get {
+                       get {                           
                                if (ListManager != null) {
-                                       return ListManager.Count;
+                                       return ListManager.Count;                                       
                                }
 
                                return 0;
@@ -940,42 +978,66 @@ namespace System.Windows.Forms
 
                internal int RowHeight {
                        get {
-                               if (preferredrow_height > Font.Height + 3) {
-                                       return preferredrow_height;
+                               if (CurrentTableStyle.CurrentPreferredRowHeight > Font.Height + 3 + 1 /* line */) {
+                                       return CurrentTableStyle.CurrentPreferredRowHeight;
 
                                } else {
-                                       return Font.Height + 3;
+                                       return Font.Height + 3 + 1 /* line */;
                                }
                        }
                }
-
+               
+               internal bool ShowEditRow {
+                       get {
+                               if (ListManager != null && ListManager.CanAddRows == false) {
+                                       return false;
+                               }
+                                                               
+                               return _readonly == false;
+                       }
+               }
+               
+               // It should only be shown if there are relations that
+               // we do not support right now
+               internal bool ShowParentRowsVisible {
+                       get {
+                               //See parentrows_visible;
+                               return false;
+                       }
+               }
+               
                #endregion Private Instance Properties
 
                #region Public Instance Methods
 
+               [MonoTODO]
                public virtual bool BeginEdit (DataGridColumnStyle gridColumn, int rowNumber)
                {
-                       throw new NotImplementedException ();
+                       return false;
                }
 
                public virtual void BeginInit ()
                {
-
+                       begininit = true;
                }
 
-
                protected virtual void CancelEditing ()
-               {
-                       if (is_editing == false) {
-                               return;
+               {                       
+                       if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) {
+                               CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
                        }
-
-                       CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
+                       
+                       if (is_adding == true) {
+                               ListManager.RemoveAt (RowsCount - 1);
+                               is_adding = false;
+                       }
+                       
                        is_editing = false;
                        is_changing = false;
                        InvalidateCurrentRowHeader ();
                }
 
+               [MonoTODO]
                public void Collapse (int row)
                {
 
@@ -1003,7 +1065,7 @@ namespace System.Windows.Forms
 
                protected virtual DataGridColumnStyle CreateGridColumn (PropertyDescriptor prop, bool isDefault)
                {
-                       throw new NotImplementedException ();
+                       throw new NotImplementedException();
                }
 
                protected override void Dispose (bool disposing)
@@ -1012,17 +1074,23 @@ namespace System.Windows.Forms
                }
 
                public virtual bool EndEdit (DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort)
-               {
-                       if (is_editing == false) {
-                               return false;
-                       }
-                       
-                       if (shouldAbort) {
+               {                                               
+                       if (is_adding == true) {                                
+                               if (shouldAbort) {
+                                       ListManager.CancelCurrentEdit ();
+                               } else {
+                                       ListManager.EndCurrentEdit ();
+                                       CalcAreasAndInvalidate ();
+                               }
+                               is_adding = false;
+                       } 
+
+                       if (shouldAbort || gridColumn.ParentReadOnly ==true) {
                                gridColumn.Abort (rowNumber);
                        } else {
                                gridColumn.Commit (ListManager, rowNumber);
                        }
-                       
+
                        is_editing = false;
                        is_changing = false;
                        InvalidateCurrentRowHeader ();
@@ -1031,7 +1099,7 @@ namespace System.Windows.Forms
 
                public virtual void EndInit ()
                {
-
+                       begininit = false;
                }
 
                public void Expand (int row)
@@ -1056,7 +1124,7 @@ namespace System.Windows.Forms
 
                protected virtual string GetOutputTextDelimiter ()
                {
-                       throw new NotImplementedException ();
+                       return string.Empty;
                }
 
                protected virtual void GridHScrolled (object sender, ScrollEventArgs se)
@@ -1066,88 +1134,19 @@ namespace System.Windows.Forms
                                return;
                        }
 
-                       Rectangle invalidate = new Rectangle ();
-                       Rectangle invalidate_column = new Rectangle ();
-
-                       if (se.NewValue > horz_pixeloffset) { // ScrollRight
-                               int pixels = se.NewValue - horz_pixeloffset;
-
-                               // Columns header
-                               invalidate_column.X = grid_drawing.ColumnsHeadersArea.X + grid_drawing.ColumnsHeadersArea.Width - pixels;
-                               invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
-                               invalidate_column.Width = pixels;
-                               invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
-                               XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, -pixels, 0, false);
-
-                               // Cells
-                               invalidate.X = grid_drawing.CellsArea.X + grid_drawing.CellsArea.Width - pixels;
-                               invalidate.Y = grid_drawing.CellsArea.Y;
-                               invalidate.Width = pixels;
-                               invalidate.Height = grid_drawing.CellsArea.Height;
-                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
-
-                       } else {
-                               int pixels = horz_pixeloffset - se.NewValue;
-
-                               // Columns header
-                               invalidate_column.X = grid_drawing.ColumnsHeadersArea.X;
-                               invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
-                               invalidate_column.Width = pixels;
-                               invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
-                               XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, pixels, 0, false);
-
-                               // Cells
-                               invalidate.X =  grid_drawing.CellsArea.X;
-                               invalidate.Y =  grid_drawing.CellsArea.Y;
-                               invalidate.Width = pixels;
-                               invalidate.Height = grid_drawing.CellsArea.Height;
-                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, pixels, 0, false);
-                       }
-
-                       horz_pixeloffset = se.NewValue;
-                       grid_drawing.UpdateVisibleColumn ();
-                       Invalidate (invalidate_column);
-                       Invalidate (invalidate);
+                       ScrollToColumnInPixels (se.NewValue);
                }
 
                protected virtual void GridVScrolled (object sender, ScrollEventArgs se)
-               {                       
+               {
                        int old_first_visiblerow = first_visiblerow;
                        first_visiblerow = se.NewValue;
                        grid_drawing.UpdateVisibleRowCount ();
                        
                        if (first_visiblerow == old_first_visiblerow) {
                                return;
-                       }
-                       
-                       Rectangle invalidate = new Rectangle ();
-
-                       if (se.NewValue > old_first_visiblerow ) { // Scrolldown
-                               int scrolled_rows = se.NewValue - old_first_visiblerow;
-                               int pixels = scrolled_rows * RowHeight;
-
-                               invalidate.X =  grid_drawing.CellsArea.X;
-                               invalidate.Y =  grid_drawing.CellsArea.Y + grid_drawing.CellsArea.Height - pixels;
-                               invalidate.Width = grid_drawing.CellsArea.Width;
-                               invalidate.Height = pixels;
-
-                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, -pixels, false);
-
-                       } else { // ScrollUp
-                               int scrolled_rows = old_first_visiblerow - se.NewValue;
-                               int pixels = scrolled_rows * RowHeight;
-
-                               invalidate.X =  grid_drawing.CellsArea.X;
-                               invalidate.Y =  grid_drawing.CellsArea.Y;
-                               invalidate.Width = grid_drawing.CellsArea.Width;
-                               invalidate.Height = pixels;
-
-                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, pixels, false);
                        }                       
-                       
-                       Invalidate (invalidate);
-                       Invalidate (grid_drawing.RowsHeadersArea);
-
+                       ScrollToRow (old_first_visiblerow, first_visiblerow);
                }
 
                public HitTestInfo HitTest (Point position)
@@ -1168,14 +1167,16 @@ namespace System.Windows.Forms
 
                public bool IsSelected (int row)
                {
-                       throw new NotImplementedException ();
+                       return selected_rows[row] != null;
                }
 
+               [MonoTODO]
                public void NavigateBack ()
                {
 
                }
 
+               [MonoTODO]
                public void NavigateTo (int rowNumber, string relationName)
                {
 
@@ -1277,7 +1278,12 @@ namespace System.Windows.Forms
                protected override void OnKeyDown (KeyEventArgs ke)
                {
                        base.OnKeyDown (ke);
-                       CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown 
+                       
+                       if (ProcessGridKey (ke) == true) {
+                               ke.Handled = true;
+                       }
+
+                       CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown
                                (ke, current_cell.RowNumber, current_cell.ColumnNumber);
                }
 
@@ -1303,21 +1309,42 @@ namespace System.Windows.Forms
                        HitTestInfo testinfo;
                        testinfo = grid_drawing.HitTest (e.X, e.Y);
 
-                       if (testinfo.type == HitTestType.Cell) {
-                               
+                       switch (testinfo.type) {
+                       case HitTestType.Cell:
+                       {
                                DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column);
-                               
+
                                if (new_cell.Equals (current_cell) == false) {
                                        CancelEditing ();
                                        CurrentCell = new_cell;
-                                       is_editing = true;
-                                       is_changing = false;
-                                       CurrentTableStyle.GridColumnStyles[testinfo.Column].Edit (ListManager,
-                                               testinfo.Row, GetCellBounds (testinfo.Row, testinfo.Column),
-                                               _readonly, string.Empty, true);
-                               } else {                                        
+                                       EditCell (current_cell);
+
+                               } else {
                                        CurrentTableStyle.GridColumnStyles[testinfo.Column].OnMouseDown (e, testinfo.Row, testinfo.Column);
                                }
+
+                               break;
+                       }
+                       case HitTestType.RowHeader:
+                       {
+                               if (ctrl_pressed == false && shift_pressed == false) {
+                                       ResetSelection (); // Invalidates selected rows
+                               }
+
+                               if (shift_pressed == true) {
+                                       ShiftSelection (testinfo.Row);
+                               } else { // ctrl_pressed or single item
+                                       Select (testinfo.Row);
+                               }
+
+                               CancelEditing ();
+                               CurrentCell = new DataGridCell (testinfo.Row, current_cell.ColumnNumber);
+                               OnRowHeaderClick (EventArgs.Empty);
+                               break;
+                       }                       
+                       
+                       default:
+                               break;
                        }
                }
 
@@ -1339,6 +1366,17 @@ namespace System.Windows.Forms
                protected override void OnMouseWheel (MouseEventArgs e)
                {
                        base.OnMouseWheel (e);
+
+                       if (e.Delta > 0) {
+                               if (current_cell.RowNumber > 0) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
+                               }
+                       }
+                       else {
+                               if (current_cell.RowNumber < RowsCount - 1) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);                                 
+                               }
+                       }
                }
 
                protected void OnNavigate (NavigateEventArgs e)
@@ -1350,7 +1388,7 @@ namespace System.Windows.Forms
 
                protected override void OnPaint (PaintEventArgs pe)
                {
-                       grid_drawing.OnPaint (pe);
+                       ThemeEngine.Current.DataGridPaint (pe, this);
                }
 
                protected override void OnPaintBackground (PaintEventArgs ebe)
@@ -1412,17 +1450,115 @@ namespace System.Windows.Forms
 
                protected bool ProcessGridKey (KeyEventArgs ke)
                {
-                       throw new NotImplementedException ();
+                       if (RowsCount == 0) {
+                               return false;
+                       }
+
+                       switch (ke.KeyCode) {
+                       case Keys.ControlKey:
+                               ctrl_pressed = true;
+                               break;
+                       case Keys.ShiftKey:
+                               shift_pressed = true;
+                               break;
+                       case Keys.Up:
+                       {
+                               if (current_cell.RowNumber > 0) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber - 1, current_cell.ColumnNumber);
+                                       EditCell (current_cell);
+                               }
+                               break;
+                       }
+                       case Keys.Down:
+                       {
+                               if (current_cell.RowNumber < RowsCount - 1) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber + 1, current_cell.ColumnNumber);
+                                       EditCell (current_cell);
+                               }
+                               break;
+                       }
+                       case Keys.Tab:
+                       case Keys.Right:
+                       {                               
+                               if (current_cell.ColumnNumber + 1 < CurrentTableStyle.GridColumnStyles.Count) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber + 1);
+                                       EditCell (current_cell);
+                               }
+                               break;
+                       }
+                       case Keys.Left:
+                       {
+                               if (current_cell.ColumnNumber > 0) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber, current_cell.ColumnNumber - 1);
+                                       EditCell (current_cell);
+                               }
+                               break;
+                       }
+                       case Keys.PageUp:
+                       {
+                               if (current_cell.RowNumber > grid_drawing.VLargeChange) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber - grid_drawing.VLargeChange, current_cell.ColumnNumber);
+                               } else {
+                                       CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
+                               }
+
+                               EditCell (current_cell);
+                               break;
+                       }
+                       case Keys.PageDown:
+                       {
+                               if (current_cell.RowNumber + grid_drawing.VLargeChange < RowsCount) {
+                                       CurrentCell = new DataGridCell (current_cell.RowNumber + grid_drawing.VLargeChange, current_cell.ColumnNumber);
+                               } else {
+                                       CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
+                               }
+
+                               EditCell (current_cell);
+                               break;
+                       }
+                       case Keys.Home:
+                       {
+                               CurrentCell = new DataGridCell (0, current_cell.ColumnNumber);
+                               EditCell (current_cell);
+                               break;
+                       }
+                       case Keys.End:
+                       {
+                               CurrentCell = new DataGridCell (RowsCount - 1, current_cell.ColumnNumber);
+                               EditCell (current_cell);
+                               break;
+                       }
+                       case Keys.Delete:
+                       {                               
+                               foreach (int row in selected_rows.Keys) {
+                                       ListManager.RemoveAt (row);                                             
+                               }
+                               selected_rows.Clear ();
+                               CalcAreasAndInvalidate ();
+                               break;                                  
+                       }
+                       default:
+                               return false; // message not processed
+                       }
+
+                       return true; // message processed
                }
 
+               // Called from DataGridTextBox
                protected override bool ProcessKeyPreview (ref Message m)
                {
+                       Keys key = (Keys) m.WParam.ToInt32 ();
+                       KeyEventArgs ke = new KeyEventArgs (key);
+                       if (ProcessGridKey (ke) == true) {
+                               return true;
+                       }
+
                        return base.ProcessKeyPreview (ref m);
                }
-
+               
                protected bool ProcessTabKey (Keys keyData)
                {
-                       throw new NotImplementedException ();
+                       return false;
                }
 
                public void ResetAlternatingBackColor ()
@@ -1432,7 +1568,7 @@ namespace System.Windows.Forms
 
                public override void ResetBackColor ()
                {
-                       background_color = def_background_color;
+                       backColor = ThemeEngine.Current.DataGridBackColor;
                }
 
                public override void ResetForeColor ()
@@ -1471,8 +1607,13 @@ namespace System.Windows.Forms
                }
 
                protected void ResetSelection ()
-               {
+               {                       
+                       foreach (int row in selected_rows.Keys) {
+                               grid_drawing.InvalidateRow (row);
+                               grid_drawing.InvalidateRowHeader (row);
+                       }
 
+                       selected_rows.Clear ();
                }
 
                public void ResetSelectionBackColor ()
@@ -1487,12 +1628,21 @@ namespace System.Windows.Forms
 
                public void Select (int row)
                {
+                       if (selected_rows[row] == null) {
+                               selected_rows.Add (row, true);
+                       } else {
+                               selected_rows[row] = true;
+                       }
 
+                       grid_drawing.InvalidateRow (row);
                }
 
                public void SetDataBinding (object dataSource, string dataMember)
                {
-                       if (SetDataSource (dataSource) == false  && SetDataMember (dataMember) == false) {
+                       bool source = SetDataSource (dataSource);
+                       bool member = SetDataMember (dataMember);
+                       
+                       if (source == false  && member == false) {
                                return;
                        }
 
@@ -1556,7 +1706,7 @@ namespace System.Windows.Forms
 
                protected bool ShouldSerializePreferredRowHeight ()
                {
-                       return (parentrowsfore_color != def_parentrowsfore_color);
+                       return (preferredrow_height != def_preferredrow_height);
                }
 
                protected bool ShouldSerializeSelectionBackColor ()
@@ -1576,6 +1726,8 @@ namespace System.Windows.Forms
 
                public void UnSelect (int row)
                {
+                       selected_rows.Remove (row);
+                       grid_drawing.InvalidateRow (row);
 
                }
                #endregion      // Public Instance Methods
@@ -1587,90 +1739,339 @@ namespace System.Windows.Forms
                        grid_drawing.CalcGridAreas ();
                        Invalidate ();
                }
+               
+               private void ConnectListManagerEvents ()
+               {
+                       cached_currencymgr_events.CurrentChanged += new EventHandler (OnListManagerCurrentChanged);                     
+               }
+               
+               private void DisconnectListManagerEvents ()
+               {
+                       
+               }
 
                // EndEdit current editing operation
-               public virtual bool EndEdit (bool shouldAbort)
-               {                       
-                       return EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber], 
+               internal virtual bool EndEdit (bool shouldAbort)
+               {
+                       return EndEdit (CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber],
                                current_cell.RowNumber, shouldAbort);
                }
 
+               private void EnsureCellVisilibility (DataGridCell cell)
+               {
+                       if (cell.ColumnNumber <= first_visiblecolumn ||
+                               cell.ColumnNumber + 1 >= first_visiblecolumn + visiblecolumn_count) {                   
+                                       
+                               first_visiblecolumn = grid_drawing.GetFirstColumnForColumnVisilibility (first_visiblecolumn, cell.ColumnNumber);                                                
+                               
+                               int pixel = grid_drawing.GetColumnStartingPixel (first_visiblecolumn);
+                               ScrollToColumnInPixels (pixel);
+                       }
+
+                       if (cell.RowNumber < first_visiblerow ||
+                               cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
+
+                               if (cell.RowNumber + 1 >= first_visiblerow + visiblerow_count) {
+                                       int old_first_visiblerow = first_visiblerow;
+                                       first_visiblerow = 1 + cell.RowNumber - visiblerow_count;
+                                       grid_drawing.UpdateVisibleRowCount ();
+                                       ScrollToRow (old_first_visiblerow, first_visiblerow);
+                               }else {
+                                       int old_first_visiblerow = first_visiblerow;
+                                       first_visiblerow = cell.RowNumber;
+                                       grid_drawing.UpdateVisibleRowCount ();
+                                       ScrollToRow (old_first_visiblerow, first_visiblerow);
+                               }
+
+                               vert_scrollbar.Value = first_visiblerow;
+                       }
+               }
+               
+               internal IEnumerable GetDataSource (object source, string member)
+               {       
+                       IListSource src = (IListSource) source;
+                       IList list = src.GetList();
+                       IListSource listsource;
+                       ITypedList typedlist;
+                                       
+                       if (source is IEnumerable) {
+                               return (IEnumerable) source;
+                       }
+                       
+                       if(src.ContainsListCollection == false) {
+                               return list;
+                       }
+                       
+                       listsource = (IListSource) source;
+                       
+                       if (listsource == null) {
+                               return null;
+                       }
+                       
+                       list = src.GetList ();
+                       
+                       if (list == null) {
+                               return null;
+                       }
+                       
+                       typedlist = (ITypedList) list;
+                               
+                       if (typedlist == null) {
+                               return null;
+                       }                       
+
+                       PropertyDescriptorCollection col = typedlist.GetItemProperties (new PropertyDescriptor [0]);
+                       PropertyDescriptor prop = col.Find (member, true);
+                                                               
+                       if (prop == null) {
+                               if (col.Count > 0) {
+                                       prop = col[0];
+
+                                       if (prop == null) {
+                                               return null;
+                                       }
+                               }
+                       }
+                       
+                       IEnumerable result =  (IEnumerable)(prop.GetValue (list[0]));
+                       return result;          
+                       
+               }
+
                internal void InvalidateCurrentRowHeader ()
                {
                        grid_drawing.InvalidateRowHeader (current_cell.RowNumber);
                }
 
                private bool SetDataMember (string member)
-               {
+               {                       
                        if (member == datamember) {
                                return false;
                        }
 
                        datamember = member;
-                       real_datasource = DataSourceHelper.GetResolvedDataSource (datasource, member);
+                       real_datasource = GetDataSource (datasource, member);
+                       DisconnectListManagerEvents ();
+                       cached_currencymgr = cached_currencymgr_events = null;
                        return true;
                }
 
                private bool SetDataSource (object source)
-               {
-                       if (datasource != null && datasource.Equals (source)) {
-                               return false;
-                       }
+               {                       
 
                        if (source != null && source as IListSource != null && source as IList != null) {
                                throw new Exception ("Wrong complex data binding source");
                        }
-
+                       
+                       current_cell = new DataGridCell ();
                        datasource = source;
+                       DisconnectListManagerEvents ();
+                       cached_currencymgr = cached_currencymgr_events = null;
                        try {
-                               real_datasource = DataSourceHelper.GetResolvedDataSource (datasource, DataMember);
-                       }catch (Exception e) {
-                               datamember = "";
+                               real_datasource = GetDataSource (datasource, DataMember);
+                       }catch (Exception e) {                          
                                real_datasource = source;
                        }
-                       
+
                        OnDataSourceChanged (EventArgs.Empty);
                        return true;
                }
 
                private void SetNewDataSource ()
-               {
-                       // Create Table Style
-                       // Create columns Styles
-                       // Bind data
-
-                       current_style.DataGrid = this;
+               {                               
                        current_style.GridColumnStyles.Clear ();
-                       current_style.CreateColumnsForTable ();
-                       grid_drawing.CalcGridAreas ();
+                       current_style.CreateColumnsForTable (false);
+                       CalcAreasAndInvalidate ();                      
                }
 
+               private void OnKeyUpDG (object sender, KeyEventArgs e)
+               {
+                       switch (e.KeyCode) {
+                       case Keys.ControlKey:
+                               ctrl_pressed = false;
+                               break;
+                       case Keys.ShiftKey:
+                               shift_pressed = false;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               
+               private void OnListManagerCurrentChanged (object sender, EventArgs e)
+               {                       
+                       if (accept_listmgrevents == false) {
+                               return;
+                       }
+                       
+                       CurrentCell = new DataGridCell (cached_currencymgr_events.Position, current_cell.RowNumber);
+               }
+               
                private void OnTableStylesCollectionChanged (object sender, CollectionChangeEventArgs e)
+               {       
+                       if (ListManager != null && String.Compare (ListManager.ListName, ((DataGridTableStyle)e.Element).MappingName, true) == 0) {                     
+                               CurrentTableStyle = (DataGridTableStyle)e.Element;
+                               ((DataGridTableStyle) e.Element).CreateColumnsForTable (false);                         
+                       }
+                                               
+                       CalcAreasAndInvalidate ();
+               }
+
+               private void EditCell (DataGridCell cell)
                {
-                       Console.WriteLine ("Datagrid.TableStyles Collection Changed {0}, null {1}", e.Action,
-                               e.Element == null);
-                       /*
-                               TODO: What's up if there are columns in the incoming TableStyle
-                       */
+                       ResetSelection (); // Invalidates selected rows
+                       is_editing = false;
+                       is_changing = false;
+                       
+                       if (ShowEditRow && is_adding == false && cell.RowNumber >= RowsCount) {
+                               ListManager.AddNew ();
+                               is_adding = true;
+                               Invalidate (); // We have just added a new row
+                       }
+                       
+                       CurrentTableStyle.GridColumnStyles[cell.ColumnNumber].Edit (ListManager,
+                               cell.RowNumber, GetCellBounds (cell.RowNumber, cell.ColumnNumber),
+                               _readonly, string.Empty, true);
+               }
 
-                       CurrentTableStyle = (DataGridTableStyle)e.Element;
-                       CurrentTableStyle.DataGrid = this;
+               private void ShiftSelection (int index)
+               {
+                       int shorter_item = -1, dist = RowsCount + 1, cur_dist;                  
+
+                       foreach (int row in selected_rows.Keys) {
 
-                       switch (e.Action)  {
-                               case CollectionChangeAction.Add: {
-                                       ((DataGridTableStyle) e.Element).CreateColumnsForTable ();
-                                       break;
+                               if (row > index) {
+                                       cur_dist = row - index;
+                               }
+                               else {
+                                       cur_dist = index - row;
                                }
-                               case CollectionChangeAction.Remove:
-                                       break;
-                               case CollectionChangeAction.Refresh:
-                                       break;
 
-                               default:
-                                       break;
+                               if (cur_dist < dist) {
+                                       dist = cur_dist;
+                                       shorter_item = row;
+                               }
                        }
 
+                       if (shorter_item != -1) {
+                               int start, end;
+
+                               if (shorter_item > index) {
+                                       start = index;
+                                       end = shorter_item;
+                               } else {
+                                       start = shorter_item;
+                                       end = index;
+                               }
+
+                               ResetSelection ();
+                               for (int idx = start; idx <= end; idx++) {
+                                       Select (idx);
+                               }
+                       }
                }
+
+               private void ScrollToColumnInPixels (int pixel)
+               {
+                       Rectangle invalidate = new Rectangle ();
+                       Rectangle invalidate_column = new Rectangle ();
+
+                       if (pixel > horz_pixeloffset) { // ScrollRight
+                               int pixels = pixel - horz_pixeloffset;
+                               
+                               horz_pixeloffset = horiz_scrollbar.Value = pixel;
+                               grid_drawing.UpdateVisibleColumn ();
+
+                               // Columns header
+                               invalidate_column.X = grid_drawing.ColumnsHeadersArea.X + grid_drawing.ColumnsHeadersArea.Width - pixels;
+                               invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
+                               invalidate_column.Width = pixels;
+                               invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
+                               XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, -pixels, 0, false);
+
+                               // Cells
+                               invalidate.X = grid_drawing.CellsArea.X + grid_drawing.CellsArea.Width - pixels;
+                               invalidate.Y = grid_drawing.CellsArea.Y;
+                               invalidate.Width = pixels;
+                               invalidate.Height = grid_drawing.CellsArea.Height;
+                               
+                               
+                               if (columnheaders_visible == true) {
+                                       invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
+                                       invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
+                               }
+                               
+                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
+                               Invalidate (invalidate_column);
+                               Invalidate (invalidate);
+
+
+                       } else {
+                               int pixels = horz_pixeloffset - pixel;
+                               Rectangle area = grid_drawing.CellsArea;
+                               
+                               horz_pixeloffset = horiz_scrollbar.Value = pixel;
+                               grid_drawing.UpdateVisibleColumn ();
+
+                               // Columns header
+                               invalidate_column.X = grid_drawing.ColumnsHeadersArea.X;
+                               invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
+                               invalidate_column.Width = pixels;
+                               invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
+                               //XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, pixels, 0, false);
+
+                               // Cells
+                               invalidate.X =  grid_drawing.CellsArea.X;
+                               invalidate.Y =  grid_drawing.CellsArea.Y;
+                               invalidate.Width = pixels;
+                               invalidate.Height = grid_drawing.CellsArea.Height;
+                               
+                               if (columnheaders_visible == true) {
+                                       invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
+                                       invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
+                                       area.Y -= grid_drawing.ColumnsHeadersArea.Height;
+                                       area.Height += grid_drawing.ColumnsHeadersArea.Height;
+                               }
+                               
+                               XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
+                               Invalidate (invalidate);
+                       }               
+                       
+               }
+
+               private void ScrollToRow (int old_row, int new_row)
+               {
+                       Rectangle invalidate = new Rectangle ();                        
+                       
+                       if (new_row > old_row) { // Scrolldown
+                               int scrolled_rows = new_row - old_row;
+                               int pixels = scrolled_rows * RowHeight;
+                               Rectangle rows_area = grid_drawing.CellsArea; // Cells area - partial rows space
+                               rows_area.Height = grid_drawing.CellsArea.Height - grid_drawing.CellsArea.Height % RowHeight;
+                               
+                               invalidate.X =  grid_drawing.CellsArea.X;
+                               invalidate.Y =  grid_drawing.CellsArea.Y + rows_area.Height - pixels;
+                               invalidate.Width = grid_drawing.CellsArea.Width;
+                               invalidate.Height = pixels;
+
+                               XplatUI.ScrollWindow (Handle, rows_area, 0, -pixels, false);
+
+                       } else { // ScrollUp
+                               int scrolled_rows = old_row - new_row;                          
+                               int pixels = scrolled_rows * RowHeight;
+
+                               invalidate.X =  grid_drawing.CellsArea.X;
+                               invalidate.Y =  grid_drawing.CellsArea.Y;
+                               invalidate.Width = grid_drawing.CellsArea.Width;
+                               invalidate.Height = pixels;
+                               XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, pixels, false);                                
+                       }
+
+                       // Right now we use ScrollWindow Invalidate, let's leave remarked it here for X11 if need it
+                       //Invalidate (invalidate);
+                       Invalidate (grid_drawing.RowsHeadersArea);
+               }
+
                #endregion Private Instance Methods