Hi
I fairly new to C# but am getting to grips with this great control.
I am just having a "mind blockage" with the concept of where and how to hook into the cell events.
For example, I have a blank cell into which I type a value, I then use this value to look up in a database table a record and the fill in the rest of the grid row with these values.
At which point can I "hook" into the grid cell events to trigger this action. I feel sure it will be simple but I just cannot figure it at the moment.
Regards
Roger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Basically I use an object oriented approach.
Each cell has a list of Controller class. When a cell receive an event (MouseDown, KeyPress, ValueChanged, ...) a method of each Controller is executed.
You can create a custom Controller and override any methods.
The advantage is that the controller class can be reused and basically you don't have to rewrite each time similar code when you want to insert the same feature in another grid/form/application. All you have to do is to correctly initialize the grid.
Some progress, but I forgot to mention that I am using the DataGrid object and so had some problems with the casting in the Controller Examples.. I have solved that (I think!) but now I cannot pull the cell value as it doesn't have a "Value" property?
My Code
public override void OnKeyDown(SourceGrid.CellContext sender, KeyEventArgs e)
{
base.OnKeyDown(sender, e);
if (e.KeyCode == Keys.Enter)
{
// Look up value
int row = sender.Position.Row;
SourceGrid.DataGrid grid = (SourceGrid.DataGrid)sender.Grid;
SourceGrid.Cells.DataGrid.Cell cell = (SourceGrid.Cells.DataGrid.Cell)sender.Cell;
string val = (string)cell.Value <====== ERRORS
// Create Connection
.....
.....
etc....
}
}
I have tried going down the
string val = (string)cell.Editor...... etc path but cannot get the correct syntax?
I can see the value in the Debugger window, but my in-experience is holding me back :-(
Hope you can point me in correct way
Roger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Usually to read and write values a GridVirtual derived control (like DataGrid) the best solution is to write and read the values directly from the data source.
You must remember that the GridVirtual doesn't contains the values but are readed directly from the DataSource, this is by design.
OK - All is looking much better now, but I still have an issue which is to do with adding a custom editor and the focus remains on the control and does not fire the OnValueChangedEvent for me to do my search code. It is almost as though it is failing a validation.
If I make an editor like so:
SourceGrid.Cells.Editor.TextBox editorString = new SourceGrid.Cells.Editor.TextBox(typeof(string));
and then add to cell like: dataCell.Editor = editorString it works fine. ie it call the OnValueChangedEvent. But I need more functionality in the TextBox - I want to have different colour on Entry, I want to have "Enter" work like Tab key, I want to disable the "Arrow" keys etc. So if I make a new class as Editor like so:
public class GridAlphaNumericTextBox : SourceGrid.Cells.Editors.EditorControlBase
{
public GridAlphaNumericTextBox()
:base(typeof(GridTextBox))
{
}
protected override Control CreateControl()
{
GridTextBox l_gridalphanumerictextbox = new GridTextBox();
return l_gridalphanumerictextbox;
}
public override void SetEditValue(object editValue)
{
Control.Text = (string)editValue;
}
public override object GetEditedValue()
{
return Control.Text;
}
}
public class GridTextBox : System.Windows.Forms.TextBox
{
public GridTextBox()
{
}
}
NOTE: I have only shown the BASIC classes - once it is working I can then build the added functionality into the derived classes.
I then add the Custom editor to the Cell Column as:
GridAlphaNumericTextBox newCustomEditor = new GridAlphaNumericTextBox();
dataCell.Editor = newCustomEditor;
Now, when I enter text into the cell, it simply stays there and the only way to come out of the cell is to hit ESC ?
Any clues?
Rgds
Roger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The editor cell type is wrong.
Replace this line:
base(typeof(GridTextBox))
with
base(typeof(string))
The base constructor takes as parameter the type of value to edit not the type of the control. For example if you use a DateTimePicker you must set the value to DateTime, if you want to edit a string using a TextBox you must use a String type, ...
This error cause the cell to consider the value wrong because it is not of type GridTextBox.
Davide
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can use the Grid.Selection.Focus method. Consider that you can call this method only when the grid can receive the focus and it is fully loaded. For example you can use it inside a Form_Load event. In this case you can for example use the first Form Activate event.
Davide
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am still having problems with the Focus onto a new column using the code above in the OnValueChanged event as posted above
the line
SourceGrid.Position newPosn = SourceGrid.Position(row,4);
grid.Selection.Focus(newPosn) <====== Does NOT work?
I think it is something to do with the fact that the 'grid' reference is derived from the sender object and not the actual grid I need to move column focus
If I try to reference the actual grid directly like this
SourceGrid.Position newPosition = new SourceGrid.Position(0, 3);
myGrid.Selection.Focus(newPosition, true);
I get an error in compiler of "Error 2 Cannot access a nonstatic member of outer type 'Wessex.frmIncineration' via nested type 'Wessex.frmIncineration.txtSearchController' C:\Documents and Settings\roger.CRAYFORDLTD\My Documents\Visual Studio 2005\Wessex_v2\frmIncineration.cs 695 21 Wessex"
How can I reference back to the actual grid?
Roger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think that the first code is right. The grid control is a reference type so you can use it without problem.
I think that the problem is that in the ValueChanged event you can't move the focus, because there are some other code that already change it after this event to set the focus again on the cell.
Unfortunately for not I think that there isn't a solution. I will think about it...
Davide
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi
I fairly new to C# but am getting to grips with this great control.
I am just having a "mind blockage" with the concept of where and how to hook into the cell events.
For example, I have a blank cell into which I type a value, I then use this value to look up in a database table a record and the fill in the rest of the grid row with these values.
At which point can I "hook" into the grid cell events to trigger this action. I feel sure it will be simple but I just cannot figure it at the moment.
Regards
Roger
Basically I use an object oriented approach.
Each cell has a list of Controller class. When a cell receive an event (MouseDown, KeyPress, ValueChanged, ...) a method of each Controller is executed.
You can create a custom Controller and override any methods.
The advantage is that the controller class can be reused and basically you don't have to rewrite each time similar code when you want to insert the same feature in another grid/form/application. All you have to do is to correctly initialize the grid.
For more informations try to look at this example:
(In the example below I populate some columns based on the value on the first column)
https://sourceforge.net/tracker/index.php?func=detail&aid=1594081&group_id=178155&atid=888231
or
https://sourceforge.net/tracker/index.php?func=detail&aid=1574604&group_id=178155&atid=888231
or
http://www.devage.com/SourceGrid/SourceGrid_EN.html#Controller
Davide
Excellent, Davide - Thanks.
I will work through those examples which I am sure will help a lot.
Roger
Davide,
Some progress, but I forgot to mention that I am using the DataGrid object and so had some problems with the casting in the Controller Examples.. I have solved that (I think!) but now I cannot pull the cell value as it doesn't have a "Value" property?
My Code
public override void OnKeyDown(SourceGrid.CellContext sender, KeyEventArgs e)
{
base.OnKeyDown(sender, e);
if (e.KeyCode == Keys.Enter)
{
// Look up value
int row = sender.Position.Row;
SourceGrid.DataGrid grid = (SourceGrid.DataGrid)sender.Grid;
SourceGrid.Cells.DataGrid.Cell cell = (SourceGrid.Cells.DataGrid.Cell)sender.Cell;
string val = (string)cell.Value <====== ERRORS
// Create Connection
.....
.....
etc....
}
}
I have tried going down the
string val = (string)cell.Editor...... etc path but cannot get the correct syntax?
I can see the value in the Debugger window, but my in-experience is holding me back :-(
Hope you can point me in correct way
Roger
Usually to read and write values a GridVirtual derived control (like DataGrid) the best solution is to write and read the values directly from the data source.
You must remember that the GridVirtual doesn't contains the values but are readed directly from the DataSource, this is by design.
In your case I suggest to use this code:
System.Data.DataRowView dataRow = dataGrid.Rows.IndexToDataSourceRow(row);
Then you can use the system DataRowView to read or write any value.
//Example
object val = dataRow["YourColumn"];
Davide
OK - All is looking much better now, but I still have an issue which is to do with adding a custom editor and the focus remains on the control and does not fire the OnValueChangedEvent for me to do my search code. It is almost as though it is failing a validation.
If I make an editor like so:
SourceGrid.Cells.Editor.TextBox editorString = new SourceGrid.Cells.Editor.TextBox(typeof(string));
and then add to cell like: dataCell.Editor = editorString it works fine. ie it call the OnValueChangedEvent. But I need more functionality in the TextBox - I want to have different colour on Entry, I want to have "Enter" work like Tab key, I want to disable the "Arrow" keys etc. So if I make a new class as Editor like so:
public class GridAlphaNumericTextBox : SourceGrid.Cells.Editors.EditorControlBase
{
public GridAlphaNumericTextBox()
:base(typeof(GridTextBox))
{
}
protected override Control CreateControl()
{
GridTextBox l_gridalphanumerictextbox = new GridTextBox();
return l_gridalphanumerictextbox;
}
public override void SetEditValue(object editValue)
{
Control.Text = (string)editValue;
}
public override object GetEditedValue()
{
return Control.Text;
}
}
public class GridTextBox : System.Windows.Forms.TextBox
{
public GridTextBox()
{
}
}
NOTE: I have only shown the BASIC classes - once it is working I can then build the added functionality into the derived classes.
I then add the Custom editor to the Cell Column as:
GridAlphaNumericTextBox newCustomEditor = new GridAlphaNumericTextBox();
dataCell.Editor = newCustomEditor;
Now, when I enter text into the cell, it simply stays there and the only way to come out of the cell is to hit ESC ?
Any clues?
Rgds
Roger
The editor cell type is wrong.
Replace this line:
base(typeof(GridTextBox))
with
base(typeof(string))
The base constructor takes as parameter the type of value to edit not the type of the control. For example if you use a DateTimePicker you must set the value to DateTime, if you want to edit a string using a TextBox you must use a String type, ...
This error cause the cell to consider the value wrong because it is not of type GridTextBox.
Davide
Great! Thanks again Davide - its working fine now.
Do you have any examples of programmatically setting focus onto a particular cell?
Roger
Hi,
You can use the Grid.Selection.Focus method. Consider that you can call this method only when the grid can receive the focus and it is fully loaded. For example you can use it inside a Form_Load event. In this case you can for example use the first Form Activate event.
Davide
I can Focus onto the Cell, but what I need is to automatically begin Editing.
I have acheived part of what I am looking for by adding code to my txtSearchController class
When I call from my program:
SourceGrid.Position focusPosn = new SourceGrid.Position(1,1)
myGrid.Selection.Focus(focusPosn);
It works fine, the focus moves to the cell and with the changes below, the cell activates for editing
ie.
public class txtSearchController : SourceGrid.Cells.Controllers.ControllerBase
{
public txtSearch Controller()
{
}
public override void OnFocusEntered(SourceGrid.CellContext sender, EventArgs e)
{
base.OnFocusEntered(sender, e);
SourceGrid.CellContext context = (SourceGrid.CellContext)sender;
context.StartEdit;
}
public override void OnFocusLeft(SourceGrid.CellContext sender, EventArgs e)
{
base.OnFocusLeftd(sender, e);
SourceGrid.CellContext context = (SourceGrid.CellContext)sender;
context.EndEdit(false);
}
public override void OnValueChanged(SourceGrid.CellContext sender, EventArgs e)
{
base.OnValueChanged(sender, e);
// Look up Value..
int row = sender.Position.Row;
SourceGrid.DataGrid grid = (SourceGrid.DataGrid)sender.Grid;
SourceGrid.Cells.DataGrid.Cell cell = (SourceGrid.Cells.DataGrid.Cell)sender.Cell;
System.Data.DataRowView dataRow = grid.Rows.IndexToDataSource(row);
object val = dataRow["myfield1"].ToString();
//
// Do search and populate the dataRow with grid positions 2,3,4
//
dataRow["myfield2"] = dsQuery.Tables[0].Rows[0].["myfield2"]
dataRow["myfield3"] = dsQuery.Tables[0].Rows[0].["myfield3"]
dataRow["myfield4"] = dsQuery.Tables[0].Rows[0].["myfield4"]
//
// Move Focus to column 4 - myfield4
//
SourceGrid.Position newPosn = SourceGrid.Position(row,4);
grid.Selection.Focus(newPosn) <====== Does NOT work?
}
Although the auto-selection to edit is working, is there a better way of doing it?
Should I be doing the focus to next cell on a different event?
I am determined to get to grips with this control !!
Regards
Roger
Hi,
You can set the Editor.EditableMode property. This is an enum flags that you can set to:
Editor.EditableMode |= EditableMode.Focus
In this way each time the cell receive the focus the edit automatically start. So you can remove your controller.
Davide
Hi Davide
I am still having problems with the Focus onto a new column using the code above in the OnValueChanged event as posted above
the line
SourceGrid.Position newPosn = SourceGrid.Position(row,4);
grid.Selection.Focus(newPosn) <====== Does NOT work?
I think it is something to do with the fact that the 'grid' reference is derived from the sender object and not the actual grid I need to move column focus
If I try to reference the actual grid directly like this
SourceGrid.Position newPosition = new SourceGrid.Position(0, 3);
myGrid.Selection.Focus(newPosition, true);
I get an error in compiler of "Error 2 Cannot access a nonstatic member of outer type 'Wessex.frmIncineration' via nested type 'Wessex.frmIncineration.txtSearchController' C:\Documents and Settings\roger.CRAYFORDLTD\My Documents\Visual Studio 2005\Wessex_v2\frmIncineration.cs 695 21 Wessex"
How can I reference back to the actual grid?
Roger
Hi,
I think that the first code is right. The grid control is a reference type so you can use it without problem.
I think that the problem is that in the ValueChanged event you can't move the focus, because there are some other code that already change it after this event to set the focus again on the cell.
Unfortunately for not I think that there isn't a solution. I will think about it...
Davide