We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Overridden GridControls and Splitters

Hi, I''m overridding the GridControl, and I''ve just added a splitter with fairly disasterous results. I''m guessing that I''ll need to copy the properties of the existing grid into the new grid, as well as hooking the events. However, I''d like to know when the best place for this is? Is there a special constructor that the splitter uses when it copy/creates the grid? Or is the PaneCreated event a better place (I''d like to avoid this event since I''d need to either expose a lot of private properties or create a special public copy function). Also, I''ve got a gridAwareTextBox hooked to the grid. Is there a pane activitating type event I can hook to rewire the text box when the active pane changes? Thanks, Sue

18 Replies

AD Administrator Syncfusion Team January 27, 2004 09:22 AM UTC

PaneCreated and PaneClosing are the places to subscribe and unsubscribe to events. You can try subscribing to teh e.Control Enter and Leave events to wire and unwire teh GridAwaretextBox. private void splitterControl1_PaneCreated(object sender, SplitterPaneEventArgs e) { Console.WriteLine("Created: " + e.ToString()); e.Control.Enter += new EventHandler(control_Enter); e.Control.Leave += new EventHandler(control_Leave); } private void splitterControl1_PaneClosing(object sender, SplitterPaneEventArgs e) { Console.WriteLine("Closed: " + e.ToString()); e.Control.Leave -= new EventHandler(control_Leave); e.Control.Enter -= new EventHandler(control_Enter); } private void control_Leave(object sender, EventArgs e) { GridControl grid = sender as GridControl; if(grid != null) { //....do what you need } } private void control_Enter(object sender, EventArgs e) { GridControl grid = sender as GridControl; if(grid != null) { //....do what you need } }


SH Sue Harris January 27, 2004 06:03 PM UTC

Thanks Clay, I''ve followed your suggestion about PaneCreated and PaneClosing, but I''m having some strange problems with (presumably) shared information about the (virtual) grids. In my overridden GridControl class, I override OnQueryRowCount. If in my override, the row count is reduced, I''m still getting calls afterwards to OnQueryRowHeight and OnQueryCellInfo for row indexes greater than the new row count. I can usually ignore these invalid row indexes, but I''d prefer not to get them at all. Do you know why they''re occurring? Thanks, Sue


AD Administrator Syncfusion Team January 27, 2004 06:25 PM UTC

When you do something that will trigger a a change in the rowcount, try calling grid.ResetVolatileData (and maybe grid.UpdateScrollBars). For example, if your external data is a DataTable, and you add new rows to the DataTable, then you should call grid.ResetVolatileData().


SH Sue Harris January 27, 2004 06:55 PM UTC

It actually is a ResetVolatileData call that starts the problem. I''ve done a sample program (using the Splitter sample) where I added a button to the form and call ResetVolatileData, then Refresh in the OnClick event. The OnQueryRowCount reduces the row count: protected override void OnQueryRowCount(GridRowColCountEventArgs e) { rowCount--; e.Count = rowCount; e.Handled = true; base.OnQueryRowCount (e); } but just afterwards I get OnQueryRowHeight called (another override) and e.Index > rowCount is true. This problem only occurs when I''ve got a splitter active, so if I click the button prior to splitting the grid, it works fine. Any ideas?


AD Administrator Syncfusion Team January 27, 2004 08:12 PM UTC

If you are using a derived grid, have you overridden CreateNewControl to create a new instance of your derived grid. Otherwise, when the grids are created for new panes, then instances of GridControls are created, and not instances of your derived grid.


SH Sue Harris January 27, 2004 11:37 PM UTC

Thanks Clay, that was exactly the override I was looking for in copying my properties. However, as for the problem with the row count, I''ve determined that when a grid is split, the OnQueryRowCount base method triggers OnQueryRowHeight for all rows in the previous row count. By that time, I''ve updated all my variables to reflect the new row count, but the RowCount in the grid has not yet been updated. Is this a bug/problem in the grid, or should I be waiting until after the OnQueryRowCount base call is finished before updating my objects (and if so, can I be sure that all the events will be triggered for my new rows, after the OnQueryRowCount has finished). Thanks, Sue


AD Administrator Syncfusion Team January 28, 2004 07:45 AM UTC

In your OnQueryRowCount, try ommitting the call to the baseclass. If you set e.Handled = true, then there is no need to call the base class as you do not want anything to change the rowcount at this point. Maybe some event handler (not checking e.Handled properly?? )associated with the splitter is resetting the value. Can you attached the sample project based on splitter sample that uses your derived grid so we can try this code here?


SH Sue Harris January 29, 2004 01:24 AM UTC

Hi Clay, I''ve attached this changed sample. The added button changes the number of rows causing the problem to occur. I''ve also noticed the row count exception also occurs in the design mode (cause the default is 0) but I''m not worried about that. thanks, Sue Splitter-CS_4824.zip


AD Administrator Syncfusion Team January 29, 2004 08:36 AM UTC

Since NewrowCoount is a property of teh derived grid, then you must change this property for evey grid since you need it to be consistant across all the grids. Also, in your derived contructor, you would have to set it to the existing value from an exisitng pane if you are creating a new pane. Another option would be to use a derived GridModel, and put the NewRowCount there. The same GridModel should be shared among all the gridcontrols in the various panes. This way set the model.NewRowCount property would set it for all panes. Here is a new button handler that just loops though all the panes and sets the NewRowCount to each exisiting gridcontrol. This avoid the problem you were seeing. private void button1_Click(object sender, System.EventArgs e) { OverrideGrid myControl; for(int i = 0; i < this.splitterControl1.RowCount; ++ i) for(int j = 0; j < this.splitterControl1.ColumnCount; ++j) { myControl = (this.splitterControl1.GetPane(i,j) as OverrideGrid); if(myControl != null) { Console.WriteLine("adjusted pane {0},{1}", i, j); myControl.NewRowCount = myControl.NewRowCount - 3; } } myControl = (this.splitterControl1.GetPane(0,0) as OverrideGrid); myControl.ResetVolatileData(); myControl.Refresh(); }


SH Sue Harris January 29, 2004 07:50 PM UTC

I original modelled the sample that way because I also change the row count in a click event on the grid (which only occurs in one grid). I can certainly fix the problem by using a shared derived Model (thanks for the suggestion), but is there a way from the grid to know its splitter siblings for other instances? As for using a derived Model class, other than the CreateNewControl and constructors, is there any other places where I''ll need to create my overriden Model class. Thanks, Sue


AD Administrator Syncfusion Team January 29, 2004 08:36 PM UTC

No. The splitter knows the controls that it has created. You would have to access them through the splitter. You would create exactly one GridModel object, and then use that object both when you create teh initial grid (by passing the Model in the constructor), and use it again in your CreateNewControl override when you create the new instances. I think that should be it. You could add a GridModel property to point to the parent splitter. That way, you could get at the splitter from any grid instance.


SH Sue Harris February 16, 2004 09:21 PM UTC

Clay, I tried overriding the GridModel object, but for some reason the Default Column width now defaults to 0. I fear that some other properties also aren''t getting initialised properly. My code change is effectively: public class OverrideModel : Syncfusion.Windows.Forms.Grid.GridModel { public OverrideModel() : base() { } } public class OverrideGrid : Syncfusion.Windows.Forms.Grid.GridControl { public override Control CreateNewControl(Control parent, int row, int column) { OverrideGrid newMe = base.CreateNewControl (parent, row, column) as OverrideGrid; newMe.Model = this.Model; return newMe; } public OverrideGrid( ) : base(new OverrideModel() ) ... (otherwise unchanged from previous example) Is there anything that I''ve missed? Do I need to initialise any properties? Please help me figure out why the default column width isn''t being set anymore. Thanks, Sue >No. The splitter knows the controls that it has created. You would have to access them through the splitter. > >You would create exactly one GridModel object, and then use that object both when you create teh initial grid (by passing the Model in the constructor), and use it again in your CreateNewControl override when you create the new instances. I think that should be it. > >You could add a GridModel property to point to the parent splitter. That way, you could get at the splitter from any grid instance.


AD Administrator Syncfusion Team February 16, 2004 10:16 PM UTC

Try overriding CreateNewControl. This should use the same gridmodel as the original control. If you need to initialze additional properties, you can do so at this time. public override Control CreateNewControl(Control parent, int row, int column) { OverrideGrid grid1 = new OverrideGrid(this.Model); return grid1; }


SH Sue Harris February 16, 2004 10:52 PM UTC

I actually have (its above the constructor). But the default column size is a property of the GridModel (not any of my stuff), and it isn''t being initialised anymore (in any grid). So I end up with what looks like no columns, because all the columns are 0 width (instead of 65 which it is usually defaulted too). >Try overriding CreateNewControl. This should use the same gridmodel as the original control. If you need to initialze additional properties, you can do so at this time. >


AD Administrator Syncfusion Team February 17, 2004 07:43 AM UTC

I don''t know that your code and what I suggested do the same thing. (They may under the wraps, but...) Your code calls the CreateNewControl baseclass and mine does not. I got the idea from looking at how the GridDataBoundGrid handles CreateNewControl, and GridDataBoundGrid does not have the problem you are reporting. If you create a little sample project showing this problem, we can look into it here.


SH Sue Harris February 17, 2004 06:43 PM UTC

I''ve attached a very simple sample, it''s not using splitters just overriding the grid and model classes. The only file of any importance in the project is the OverrideClasses.cs Unless I re-set the grids default row and column sizes and (sometimes) the row and column count, the grid comes up blank (rather than having the normal 10 x 10 grid shown which is the default). I''m running with 2.0.2.0. Thanks, Sue GridOverrides_8730.zip


AD Administrator Syncfusion Team February 17, 2004 08:47 PM UTC

You will have to initialize things at least in one place, either in the grid''s constructor, or in the model''s constructor. Below are two samples, either which worked for me in your sample.
public OverrideGrid( ) : base( new OverrideModel() )
{
	CommandStack.Enabled = false;
	Rows.DefaultSize = 17;
	Cols.DefaultSize = 65;
	RowHeights[0] = 21;
	ColWidths[0] = 35;
	RowHeights.ResetModified();
	ColWidths.ResetModified();
	ExcelLikeCurrentCell = false;
	ExcelLikeSelectionFrame = false;
	AllowDragSelectedCols = false;
	AllowDragSelectedRows = false;
	CommandStack.Enabled = false;
	FloatCellsMode = GridFloatCellsMode.None;
	ResetBaseStylesMap();

	//GridModel model = Model;
	//model.Properties.GridLineColor = Color.FromArgb(57, 73, 122);
	this.RowCount = 10;
	this.ColCount = 10;
}

public OverrideModel() : base()
{
	CommandStack.Enabled = false;
	Rows.DefaultSize = 17;
	Cols.DefaultSize = 65;
	RowHeights[0] = 21;
	ColWidths[0] = 35;
	RowHeights.ResetModified();
	ColWidths.ResetModified();
	CommandStack.Enabled = false;
	this.RowCount = 10;
	this.ColCount = 10;
}


SH Sue Harris February 17, 2004 09:16 PM UTC

Cool, I found that the first example is copied from the internal InitializeModel method. Is there any likelihood of that method becoming a protected method? (It is exactly the method I was looking for), and unlike coping in the example, calling it would reduce the risk of future changes to the grid breaking my overridden class. Thanks, Sue

Loader.
Live Chat Icon For mobile
Up arrow icon