/// <summary> /// Returns the control attached to the specified grid panel. /// </summary> /// <param name="gridPanel">The grid panel.</param> /// <returns></returns> public virtual System.Windows.Forms.Control GetEditorControl(GridSubPanel gridPanel) { if (IsAttached(gridPanel)) { return(gridPanel.ControlsRepository[GetEditorControlGuid()]); } else { throw new MEDDataGridException("Editor not attached to the grid, call AttachEditorControl first"); } }
/// <summary> /// Draw the specified Cell /// </summary> /// <param name="p_Panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> /// <param name="p_Cell">The cell.</param> /// <param name="p_CellPosition">The cell position.</param> /// <param name="p_PanelDrawRectangle">The panel draw rectangle.</param> protected override void PaintCell(GridSubPanel p_Panel, PaintEventArgs e, Cells.ICellVirtual p_Cell, Position p_CellPosition, Rectangle p_PanelDrawRectangle) { ICell l_Cell = (ICell)p_Cell; Range l_CellRange = l_Cell.Range; if (l_CellRange.RowsCount == 1 && l_CellRange.ColumnsCount == 1) { base.PaintCell(p_Panel, e, p_Cell, p_CellPosition, p_PanelDrawRectangle); } else // Row/Col Span > 1 { Rectangle l_Rect = p_Panel.RectangleGridToPanel(PositionToDisplayRect(l_CellRange.Start)); base.PaintCell(p_Panel, e, p_Cell, l_CellRange.Start, l_Rect); } }
/// <summary> /// Start editing the cell passed. Do not call this method for start editing a cell, you must use Cell.StartEdit. /// </summary> /// <param name="p_Cell">Cell to start edit</param> /// <param name="p_Position">Editing position(Row/Col)</param> /// <param name="p_StartEditValue">Can be null(in this case use the p_cell.Value</param> public override void InternalStartEdit(Cells.ICellVirtual p_Cell, Position p_Position, object p_StartEditValue) { base.InternalStartEdit(p_Cell, p_Position, p_StartEditValue); if (p_Cell == null) { throw new ArgumentNullException("p_Cell"); } if (p_Cell.Grid == null) { throw new SourceGridException("Cell is not bounded to a grid"); } if (p_Cell.Grid.FocusCellPosition != p_Position) { throw new SourceGridException("Cell must have the focus"); } if (IsEditing == false && EnableEdit) { //verifico di non avere ancora una cella associata if (EditCell != null) { throw new SourceGridException("There is already a Cell in edit state"); } GridSubPanel l_Panel = p_Cell.Grid.PanelAtPosition(p_Position); if (l_Panel == null) { throw new SourceGridException("Invalid Cell Position, panel not found"); } AttachEditorControl(l_Panel); Control l_EditorControl = GetEditorControl(l_Panel); p_Cell.Grid.LinkedControls[l_EditorControl] = p_Position; //aggiorno la posizione p_Cell.Grid.RefreshLinkedControlsBounds(); l_EditorControl.Show(); l_EditorControl.BringToFront(); l_EditorControl.Focus(); SetEditCell(p_Cell, p_Position); //con questa chiamata inizia logicamente l'edit //p_Cell.Grid.InvalidateCell(p_Position); } }
/// <summary> /// Start editing the cell passed. Do not call this method for start editing a cell, you must use Cell.StartEdit. /// </summary> /// <param name="p_Cell">Cell to start edit</param> /// <param name="position">Editing position(Row/Col)</param> /// <param name="p_StartEditValue">Can be null(in this case use the p_cell.Value</param> public override void InternalStartEdit(Cells.ICellVirtual p_Cell, Position position, object p_StartEditValue) { base.InternalStartEdit(p_Cell, position, p_StartEditValue); if (p_Cell == null) { throw new ArgumentNullException("p_Cell"); } if (p_Cell.Grid == null) { throw new MEDDataGridException("Cell is not bounded to a grid"); } if (p_Cell.Grid.FocusCellPosition != position) { p_Cell.Grid.SetFocusCell(position); } if (IsEditing == false && EnableEdit) { // Verify that the cell is still associated. if (EditCell != null) { throw new MEDDataGridException("There is already a Cell in edit state"); } GridSubPanel l_Panel = p_Cell.Grid.PanelAtPosition(position); if (l_Panel == null) { throw new MEDDataGridException("Invalid Cell Position, panel not found"); } AttachEditorControl(l_Panel); Control l_EditorControl = GetEditorControl(l_Panel); p_Cell.Grid.LinkedControls[l_EditorControl] = position; // update the position p_Cell.Grid.RefreshLinkedControlsBounds(); l_EditorControl.Show(); l_EditorControl.BringToFront(); l_EditorControl.Focus(); SetEditCell(p_Cell, position); // Start the edit ////p_Cell.Grid.InvalidateCell(position); } }
/// <summary> /// Remove the current editor from the grid panel. /// </summary> /// <param name="p_GridPanel">The grid panel.</param> public virtual void DetachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel)) { Control l_EditorControl = GetEditorControl(p_GridPanel); l_EditorControl.Validated -= new EventHandler(InnerControl_Validated); // A .Net application can't close when a active control is removed from the // control collection so change the focus first. if (l_EditorControl.ContainsFocus) { p_GridPanel.Grid.SetFocusOnCells(); } l_EditorControl.Hide(); p_GridPanel.ControlsRepository.Remove(GetEditorControlGuid()); } }
/// <summary> /// Remove the current editor from the grid panel. /// </summary> /// <param name="p_GridPanel"></param> public virtual void DetachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel)) { Control l_EditorControl = GetEditorControl(p_GridPanel); //m_Control.KeyDown -= new KeyEventHandler(InnerControl_KeyDown); //l_EditorControl.Validating -= new System.ComponentModel.CancelEventHandler(InnerControl_Validating); l_EditorControl.Validated -= new EventHandler(InnerControl_Validated); //.Net bug : application doesn't close when a active control is removed from the control collection // change the focus first if (l_EditorControl.ContainsFocus) { p_GridPanel.Grid.SetFocusOnCells(); } l_EditorControl.Hide(); p_GridPanel.ControlsRepository.Remove(GetEditorControlGuid()); } }
/// <summary> /// Add the current editor to the grid panel. /// </summary> /// <param name="p_GridPanel">The grid panel.</param> public virtual void AttachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel) == false) { p_GridPanel.SuspendLayout(); try { Control l_EditorControl = CreateEditorControl(); l_EditorControl.Visible = false; p_GridPanel.ControlsRepository.Add(GetEditorControlGuid(), l_EditorControl); l_EditorControl.CreateControl(); l_EditorControl.Validated += new EventHandler(InnerControl_Validated); } finally { p_GridPanel.ResumeLayout(true); } } }
/// <summary> /// Add the current editor to the grid panel. /// </summary> /// <param name="p_GridPanel">The grid panel.</param> public virtual void AttachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel) == false) { p_GridPanel.SuspendLayout(); try { Control l_EditorControl = CreateEditorControl(); l_EditorControl.Visible = false; p_GridPanel.ControlsRepository.Add(GetEditorControlGuid(), l_EditorControl); l_EditorControl.CreateControl(); l_EditorControl.Validated += new EventHandler(InnerControl_Validated); } finally { p_GridPanel.ResumeLayout(true); } } }
/// <summary> /// Start editing the cell passed. Do not call this method for start editing a cell, you must use CellContext.StartEdit. /// </summary> /// <param name="cellContext">Cell to start edit</param> internal override void InternalStartEdit(CellContext cellContext) { base.InternalStartEdit(cellContext); if (Control == null) { throw new SourceGridException("Control cannot be null"); } if (IsEditing == false && EnableEdit) { //verifico di non avere ancora una cella associata if (EditCell != null) { throw new SourceGridException("There is already a Cell in edit state"); } GridSubPanel panel = cellContext.Grid.PanelAtPosition(cellContext.Position); if (panel == null) { throw new SourceGridException("Invalid Cell Position, panel not found"); } if (IsControlAttached(panel) == false) { AttachControl(panel); } cellContext.Grid.LinkedControls.Add(Control, new LinkedControlValue(cellContext.Position)); //aggiorno la posizione cellContext.Grid.ArrangeLinkedControls(); OnStartingEdit(cellContext, Control); SetEditCell(cellContext); //con questa chiamata inizia logicamente l'edit SafeSetEditValue(cellContext.Cell.Model.ValueModel.GetValue(cellContext)); } }
/// <summary> /// Add the current editor to the grid panel. /// </summary> /// <param name="p_GridPanel"></param> public virtual void AttachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel) == false) { p_GridPanel.SuspendLayout(); try { Control l_EditorControl = CreateEditorControl(); l_EditorControl.Visible = false; p_GridPanel.ControlsRepository.Add(GetEditorControlGuid(), l_EditorControl); l_EditorControl.CreateControl(); //m_Control.KeyDown += new KeyEventHandler(InnerControl_KeyDown); //l_EditorControl.Validating += new System.ComponentModel.CancelEventHandler(InnerControl_Validating); l_EditorControl.Validated += new EventHandler(InnerControl_Validated); } finally { p_GridPanel.ResumeLayout(true); } } }
/// <summary> /// Add the Control to the specified panel. Consider that a Control can only be a child of one Container, for this reason if you nee an editor on 2 panels you need 2 different Control, you cannot share the same editor on 2 different panels, for example the Top panel and the scrollable panel. /// </summary> /// <param name="panel"></param> private void AttachControl(GridSubPanel panel) { panel.Controls.Add(Control); Control.Validated += new EventHandler(InnerControl_Validated); }
/// <summary> /// Returns true if the control is atteched to the grid panel. /// </summary> /// <param name="p_GridPanel">The grid to check whether the control is attached</param> /// <returns></returns> public virtual bool IsAttached(GridSubPanel p_GridPanel) { return p_GridPanel.ControlsRepository.ContainsKey(GetEditorControlGuid()); }
/// <summary> /// Returns true if the control is atteched to the grid panel. /// </summary> /// <param name="p_GridPanel">The grid to check whether the control is attached</param> /// <returns></returns> public virtual bool IsAttached(GridSubPanel p_GridPanel) { return(p_GridPanel.ControlsRepository.ContainsKey(GetEditorControlGuid())); }
/// <summary> /// Draw the specified region of cells in PaintEventArgs to the specified GridSubPanel. /// </summary> /// <param name="panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> protected virtual void PanelPaint(GridSubPanel panel, PaintEventArgs e) { if (!Redraw || this.DrawColLine) { return; } // Draw BackColor (Needed due to Opaque ControlStyles) e.Graphics.Clear(BackColor); // DrawCells Range l_Range = panel.RangeAtDisplayRect(panel.RectanglePanelToGrid(e.ClipRectangle)); if (l_Range.Start.IsEmpty() == false) { PaintRange(panel, e, l_Range); } }
/// <summary> /// Draw a range of cells in the specified panel /// </summary> /// <param name="p_Panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> /// <param name="p_Range">The range.</param> protected virtual void PaintRange(GridSubPanel p_Panel, PaintEventArgs e, Range p_Range) { Rectangle l_DrawRect; l_DrawRect = p_Panel.RectangleGridToPanel(PositionToDisplayRect(p_Range.Start)); Rectangle l_AbsRect = PositionToAbsoluteRect(p_Range.Start); int l_DeltaX = l_AbsRect.Left - l_DrawRect.Left; int l_DeltaY = l_AbsRect.Top - l_DrawRect.Top; Position l_p; for (int r = p_Range.Start.Row; r <= p_Range.End.Row; ++r) { int l_Top = Rows[r].Top - l_DeltaY; int l_Height = Rows[r].Height; for (int c = p_Range.Start.Column; c <= p_Range.End.Column; ++c) { l_DrawRect.Location = new Point(Columns[c].Left - l_DeltaX, l_Top); l_DrawRect.Size = new Size(Columns[c].Width, l_Height); ICellVirtual l_Cell = GetCell(r, c); if (l_Cell != null) { l_p = new Position(r, c); if (IsCellVisible(l_p)) { PaintCell(p_Panel, e, l_Cell, l_p, l_DrawRect); } else { while (c != p_Range.End.Column && !IsCellVisible(l_p)) { c++; l_p = new Position(r, c); } } } } } }
/// <summary> /// Draw the specified Cell /// </summary> /// <param name="p_Panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> /// <param name="p_Cell">The cell.</param> /// <param name="p_CellPosition">The cell position.</param> /// <param name="p_PanelDrawRectangle">The panel draw rectangle.</param> protected virtual void PaintCell(GridSubPanel p_Panel, PaintEventArgs e, ICellVirtual p_Cell, Position p_CellPosition, Rectangle p_PanelDrawRectangle) { p_Cell.VisualModel.DrawCell(p_Cell, p_CellPosition, e, p_PanelDrawRectangle); }
/// <summary> /// Paint the specified GridSubPanel. /// </summary> /// <param name="panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> public virtual void PanelsPaint(GridSubPanel panel, PaintEventArgs e) { if (!Redraw || this.DrawColLine) { return; } // Draw BackColor (needed due to Opaque ControlStyles) e.Graphics.Clear(BackColor); // DrawCells if (e.ClipRectangle.Width > 0 && e.ClipRectangle.Height > 0) { if (panel == TopLeftPanel) { Range l_Range = TopLeftPanel.RangeAtDisplayRect(TopLeftPanel.RectanglePanelToGrid(e.ClipRectangle)); if (l_Range.Start.IsEmpty() == false) { PaintRange(TopLeftPanel, e, l_Range); } TopLeftPanel.SuspendLayout(); } if (panel == LeftPanel) { Range l_Range = LeftPanel.RangeAtDisplayRect(LeftPanel.RectanglePanelToGrid(e.ClipRectangle)); if (l_Range.Start.IsEmpty() == false) { PaintRange(LeftPanel, e, l_Range); } LeftPanel.SuspendLayout(); } if (panel == TopPanel) { Range l_Range = TopPanel.RangeAtDisplayRect(TopPanel.RectanglePanelToGrid(e.ClipRectangle)); if (l_Range.Start.IsEmpty() == false) { PaintRange(TopPanel, e, l_Range); } TopPanel.SuspendLayout(); } if (panel == ScrollablePanel) { Range l_Range = ScrollablePanel.RangeAtDisplayRect(ScrollablePanel.RectanglePanelToGrid(e.ClipRectangle)); if (l_Range.Start.IsEmpty() == false) { PaintRange(ScrollablePanel, e, l_Range); } ResumeLayoutGrid(); } } }
/// <summary> /// Returns the control attached to the specified grid panel. /// </summary> /// <param name="gridPanel">The grid panel.</param> /// <returns></returns> public virtual System.Windows.Forms.Control GetEditorControl(GridSubPanel gridPanel) { if (IsAttached(gridPanel)) { return gridPanel.ControlsRepository[GetEditorControlGuid()]; } else { throw new MEDDataGridException("Editor not attached to the grid, call AttachEditorControl first"); } }
/// <summary> /// Terminate the edit action /// </summary> /// <param name="p_Cancel">True to cancel the editing and return to normal mode, false to call automatically ApplyEdit and terminate editing</param> /// <returns>Returns true if the cell terminate the editing mode</returns> public override bool InternalEndEdit(bool p_Cancel) { if (IsEditing) { bool l_bSuccess = true; if (p_Cancel == false) { l_bSuccess = InternalApplyEdit(); } if (l_bSuccess) { if (EditCell == null) { System.Diagnostics.Debug.Assert(false); //non dovrebbe succedere ma in debug un paio di volte � capitato ma non sono riuscito a riprodurlo } else { GridVirtual l_Grid = EditCell.Grid; GridSubPanel l_Panel = l_Grid.PanelAtPosition(EditPosition); //di fatto mettendo questa property a null termina logicamente l'edit // e � importante che venga fatto appena possibile (in particolare prima della chiamata a SetFocusOnGridSubPanel perch� altrimenti questa chiamerebbe nuovamente EndEdit(false) SetEditCell(null, Position.Empty); Control l_EditorControl = null; if (IsAttached(l_Panel)) { l_EditorControl = GetEditorControl(l_Panel); } if (l_EditorControl != null) { //se il controllo ha il focus, metto il focus sulle cella in modo da forzare un eventuale validate, se il controllo non ha il fuoco il validate dovrebbe essere gi� stato chiamato if (l_Grid != null && l_EditorControl.ContainsFocus) { l_Grid.SetFocusOnCells(); } l_Grid.LinkedControls.Remove(l_EditorControl); l_EditorControl.Hide(); } else { System.Diagnostics.Debug.Assert(false); } } } else //if the ApplyEdit failed { if (EditCell != null) { GridVirtual l_Grid = EditCell.Grid; GridSubPanel l_Panel = l_Grid.PanelAtPosition(EditPosition); if (IsAttached(l_Panel)) { Control l_EditorControl = null; l_EditorControl = GetEditorControl(l_Panel); if (l_EditorControl != null && l_EditorControl.ContainsFocus == false) { l_EditorControl.Focus(); } } } } return(l_bSuccess); } else { return(true); } }
/// <summary> /// Check if the Control is attached to the specified panel. Consider that a Control can only be a child of one Container, for this reason if you nee an editor on 2 panels you need 2 different Control, you cannot share the same editor on 2 different panels, for example the Top panel and the scrollable panel. /// </summary> /// <param name="panel"></param> private bool IsControlAttached(GridSubPanel panel) { return(panel.Controls.Contains(Control)); }
/// <summary> /// Terminate the edit action /// </summary> /// <param name="p_Cancel">True to cancel the editing and return to normal mode, false to call automatically ApplyEdit and terminate editing</param> /// <returns>Returns true if the cell terminate the editing mode</returns> public override bool InternalEndEdit(bool p_Cancel) { if (!IsEditing) { return(true); } bool isSuccess = true; if (p_Cancel == false) { isSuccess = InternalApplyEdit(); } if (isSuccess) { if (EditCell == null) { throw new InvalidOperationException(); } else { GridVirtual l_Grid = EditCell.Grid; GridSubPanel l_Panel = l_Grid.PanelAtPosition(EditPosition); // In fact, setting this property to null logically ends the edit and it is // important that it is done as soon as possible (especially before the call // to SetFocusOnGridSubPanel is because otherwise this would call again EndEdit (false) SetEditCell(null, Position.Empty); Control l_EditorControl = null; if (IsAttached(l_Panel)) { l_EditorControl = GetEditorControl(l_Panel); } if (l_EditorControl != null) { // If the control has the focus, put the focus on the cell to force an eventual // validation of that. If the control has the focus it should be validated already. if (l_Grid != null && l_EditorControl.ContainsFocus) { l_Grid.SetFocusOnCells(); } l_Grid.LinkedControls.Remove(l_EditorControl); l_EditorControl.Hide(); } else { throw new InvalidOperationException(); } } } else // if the ApplyEdit failed { if (EditCell != null) { GridVirtual l_Grid = EditCell.Grid; GridSubPanel l_Panel = l_Grid.PanelAtPosition(EditPosition); if (IsAttached(l_Panel)) { Control l_EditorControl = null; l_EditorControl = GetEditorControl(l_Panel); if (l_EditorControl != null && l_EditorControl.ContainsFocus == false) { l_EditorControl.Focus(); } } } } return(isSuccess); }
/// <summary> /// Grid Constructor /// </summary> public GridVirtual() { // default double buffer SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.DoubleBuffer, true); topPanel = new GridSubPanel(this, true); topPanel.TabStop = false; leftPanel = new GridSubPanel(this, true); leftPanel.TabStop = false; topLeftPanel = new GridSubPanel(this, true); topLeftPanel.TabStop = false; scrollablePanel = new GridSubPanel(this, true); scrollablePanel.TabStop = false; hiddenFocusPanel = new GridSubPanel(this, false); hiddenFocusPanel.TabStop = true; //questo è l'unico pannello a poter ricevere il tab rows = new RowInfo.RowInfoCollection(this); rows.RowHeightChanged += new RowInfoEventHandler(rows_RowHeightChanged); rows.RowsAdded += new IndexRangeEventHandler(rows_RowsAdded); columns = new ColumnInfo.ColumnInfoCollection(this); columns.ColumnWidthChanged += new ColumnInfoEventHandler(columns_ColumnWidthChanged); columns.ColumnsAdded += new IndexRangeEventHandler(columns_ColumnsAdded); rows.RowsRemoved += new IndexRangeEventHandler(rows_RowsRemoved); columns.ColumnsRemoved += new IndexRangeEventHandler(columns_ColumnsRemoved); SuspendLayoutGrid(); Controls.Add(hiddenFocusPanel); hiddenFocusPanel.Location = new Point(0, 0); hiddenFocusPanel.Size = new Size(2, 2); topLeftPanel.Location = new Point(0, 0); Controls.Add(scrollablePanel); Controls.Add(topLeftPanel); Controls.Add(topPanel); Controls.Add(leftPanel); // hide this panel hiddenFocusPanel.SendToBack(); hiddenFocusPanel.TabIndex = 0; Size = new System.Drawing.Size(200, 200); selection = new Selection(this); ContextMenuStyle = 0; ResumeLayoutGrid(); }
/// <summary> /// Draw the specified Cell /// </summary> /// <param name="p_Panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> /// <param name="p_Cell">The cell.</param> /// <param name="p_CellPosition">The cell position.</param> /// <param name="p_PanelDrawRectangle">The panel draw rectangle.</param> protected override void PaintCell(GridSubPanel p_Panel, PaintEventArgs e, Cells.ICellVirtual p_Cell, Position p_CellPosition, Rectangle p_PanelDrawRectangle) { ICell l_Cell = (ICell)p_Cell; Range l_CellRange = l_Cell.Range; if (l_CellRange.RowsCount == 1 && l_CellRange.ColumnsCount == 1) { base.PaintCell(p_Panel, e, p_Cell, p_CellPosition, p_PanelDrawRectangle); } else // Row/Col Span > 1 { Rectangle l_Rect = p_Panel.RectangleGridToPanel(PositionToDisplayRect(l_CellRange.Start)); base.PaintCell(p_Panel, e, p_Cell, l_CellRange.Start, l_Rect); } }
/// <summary> /// Remove the current editor from the grid panel. /// </summary> /// <param name="p_GridPanel">The grid panel.</param> public virtual void DetachEditorControl(GridSubPanel p_GridPanel) { if (IsAttached(p_GridPanel)) { Control l_EditorControl = GetEditorControl(p_GridPanel); l_EditorControl.Validated -= new EventHandler(InnerControl_Validated); // A .Net application can't close when a active control is removed from the // control collection so change the focus first. if (l_EditorControl.ContainsFocus) { p_GridPanel.Grid.SetFocusOnCells(); } l_EditorControl.Hide(); p_GridPanel.ControlsRepository.Remove(GetEditorControlGuid()); } }