Hi,
I'v done a little C# WinFormApp with B2.
The App loads data to a BinddingSource via List<myClass>.
This BindingSource is bound to a DataGridView.
Everything works as expected, when I navigate via a BindingNavigator the DataGridView marks the selected row....
BUT: I can't find a way to scroll the selected row into the visual part of the DataGridView.
So I watch the selector going down - and must follow him wiht manual scrolling.
The things become worse, when I enter a number in the BindingNavigator.
Any row of the datagridview gets the selection - but how to make this visible.
There is a property -- Displayed - this shows (correct) false - but that is no help since I don't know how to scroll the thing.
There is no "EnsureVisible" like for a ListViewItem.
Does anyone know a solution
Regards
Manfred

Scrolling a DataGridView
Ehr
thanks!
-mark
Program Manager
Microsoft
This post is provided "as-is"
gabit7
you could try playing with the VScrollBar in the DataGrid.
VScrollBar v;
for (int i =0; i < dg.Controls.Count; i++) {
if (dg.Controls
v = = dg.Controls
break;
}
}
You could try to scrolldown the Scrollbar until the Displayed property of the DataGridRow is true...
cheers,
Paul June A. Domag
pawan_atl
First off, we had made a bug fix post Beta2 so that setting the current cell correctly caused the grid to scroll. I was using this recent build to try it out.
Second - Can you post more code or open a bug for your scenario. I want to investigate why it doesn't work and see if there is something we can do.
Hope this helps!
-mark
Program Manager
Microsoft
This post is provided "as-is"
Ole Preisler - MSFT
as you see I do the thing with the "FirstDisplayScrollingRwo".
But the thing with CurrentCell does not work correct.
It has the same problems as my code had.
To see how it fails try filling about twice as visible rows in a DGV.
Add a handler for the CurrentChanged in the BindingSource.
There use
dataGridView1.CurrentCell=dataGridView1.Rows[ItemBindingSource.Position].Cells[0];
to try it
Start the app and use a Navigator and do the following:
Enter a number - and watch how it works.
Click on the selected row - than back to the navigator - another number
STILL WORKS!
Now stay in the navigator enter another number that needs scrolling.
It does not work!!
The cell is selected - but scrolling does not work. It works only imideatly after the DGV had the focus.
Maybe you have the same problem than I
I encountered the following (with a handler for RowEnter of DGV):
Assume your DGV has 5 visible rows.
Row 1 is selected and visible the DGV has the focus.
In the navigator I enter 20 - in the handler i get 20 for e.RowIndex (FINE!!)
Now I drag down the scrollbar to lets say 100 and click that Row.
What I get is e.RowIndex 20 (and if not handled) e.RowIndex 100
So it looks like setting the focus (by clicking that a new row) fires a RowEnter for the current selected row.
And if you handle this first one you will get the second with a wrong index!!
It seems the control calculates the new row depending on what is visible and an offset.
For an example: you have 5 rows visible.
You select row 20 (with the mouse).
Than you use the navigator to select row 2
With row 1 is selected and visible as the first row you scroll down one page.
Be sure only to use the scrollbar and do not click into the rows!!
Now you are down and row 10 is the topmost visible.
Now click row 13.
If your handler does not take care you will get:
a.) e.RowIndex==1 (you select this thing and scroll it back in)
then
b.) e.RowIndex==3 (since you clicked an offset of 3 rows)
STRANGE
My code works now (tries to center the current row) and looks like this:
private
void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e) {if (!dataGridView1.Rows[e.RowIndex].Displayed) { //only if there is a need!
if (e.RowIndex != dataGridView1.CurrentRow.Index) { //avoid useless setting if focus set -- makes problems
// because 2 RowEnter events are fired - first for the current row (because of focus)
// and one for the new row - but the new one is calculate by the mouseposition
// so if we scroll first - a wrong row gets selected
dataGridView1.FirstDisplayedScrollingRowIndex = (e.RowIndex - m_nDisplayedRows / 2) >= 0 e.RowIndex - m_nDisplayedRows / 2 : 0;
}
}
}
Thanks for your help - maybe my investigations helps also a little
Manfred
DLG007
We had looked into an EnsureVisible but do not have the time to test it for this release.
Hope these methods help!
-mark
Program Manager
Microsoft
This post is provided "as-is"
Therese
since Pauls suggestion made me thinking about resolving it via "handmade code" I wrote a little thing which works. Not perfect - but better then not scrolling.
First i declare a variable (m_nDisplayedRows initialized with -1) for holding the number of displayed rows in the datagridview.
With this I can scroll the "invisible row" into the middel of the DGV.
Here is the code for the CurrentChanged event of the bound BindingSource.
if
(m_nDisplayedRows == -1) {bool bFoundDisplayed = false;
int nFirst = 0;
int nLast = 1; foreach (DataGridViewRow Row in dataGridView1.Rows) {
if(!bFoundDisplayed) { //till now no displayed found!
if(!Row.Displayed) { //not visilbe
continue;
}
bFoundDisplayed = true;
nFirst = Row.Index;
} else {
if (!Row.Displayed) {
break;
}
nLast = Row.Index;
}
}
m_nDisplayedRows = nLast - nFirst;
} if (!dataGridView1.CurrentRow.Displayed) {
dataGridView1.FirstDisplayedScrollingRowIndex = (dataGridView1.CurrentRow.Index-m_nDisplayedRows/2)>=0 dataGridView1.CurrentRow.Index-m_nDisplayedRows/2 : 0;
}
A littel more work than just call "EnsureVisible" - but it works
Cheers
Manfred
khaleel
I think I solved the problem!
I have a handler for the BindigSource.CurrentChanged.
This handler looks if a fiel (displayed in the DGV) is null.
If so, it loads data to the field.
If not - nothing is done!!
When data is loaded the scrolling fails - if not it works as expected!
So I placed the handling to the RowEnter event of the DGV - and now everything works fine.
Conclusio: If I change the bound data in CurrentChanged of the bindig source I distrube the scrolling logic of the DGV.
Positive: works now
Negative: took me a lot of hours
Thanks for all your help
Manfred
orit_itzhar
I made an App left everything default and added a Dataset.
In this dataset I enter two columns C1 and C2 type Int32.
Next I placed a DataGridView and a DataNavigator on the form.
And I added a handler for CurrentChanged of the BindingNavigator.
To simulate my relas world scenario - (where I load a huge BLOB field only if the row is selected) I assume that C2 is that "load if needed field".
Funny thing - watch (and try) the comment in "FormLoad".
public partial class Form1 : Form {
private bool bLoading;
public Form1() {
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e) {
DataSet1.DataTable1DataTable dT=(DataSet1.DataTable1DataTable)dataSet1.Tables[0];
DataSet1.DataTable1Row dR;
bLoading = true; //comment this line - and watch empty rows appearing :-) for (int nX = 0; nX < 20; nX++) {
dR = dT.NewDataTable1Row();
dR.C1 = nX;
dR.C2 = 0;
dT.Rows.Add(dR);
}
bLoading = false;
} private void DataTable1BindingSource_CurrentChanged(object sender, EventArgs e) {
if (!bLoading) {
DataSet1.DataTable1Row dR = ((DataRowView)DataTable1BindingSource.Current).Row as DataSet1.DataTable1Row;
if (dR != null) {
if (dR.C2 == 0) {
dR.C2 = dR.C1;
}
}
}
}
}
Cheers
Manfred
Francisco Rivas
thanks for that snippet - pretty hard I think
Especialy when I think about the "EnsureVisible" in the "old Controls".
I can't understand why such an important thing is missing in the "very best data control".
But we are in beta - maybe that changes till RTM.
Because we have perfect navigation controls, easy databing -- everything better than before - and than such a "step backward" from the old controls.
Thanks again
Manfred