I show the next selected row on top of grid using FirstDisplayedScrollingRowIndex property like this:
int currentIndex = dgvMain.FirstDisplayedScrollingRowIndex;
int[] highlightedArray = HighlightedRows.ToArray();
highlightedArray = highlightedArray.OrderBy(h => h).ToArray();
var next = highlightedArray.FirstOrDefault(r => r > currentIndex);
dgvMain.FirstDisplayedScrollingRowIndex = next;
but how can I show the next selected row on bottom of grid? I searched for a property but didn't find anything.
If there was a method or property which could tell me how many rows I see at a time, it would be helpful, something like:
dgvMain.FirstDisplayedScrollingRowIndex = next + dgvMain.RowsPerView;
lets say I see 10 rows per view, and I want to show 36th row on bottom of my grid, in this situation showing the 27th row (36 - 9) on top would do the trick, because there are 9 other rows (10 - upper row) below it.
You could use the DataGridView.DisplayedRowCount()
See this MSDN for more details
Related
I'm trying to get the row count of rows which don't have any value (any of columns)
Sample image of the Excel file I'm using:
Highlighted rows have some values in some columns rest of rows are blank I need to count those rows.
I already used this method
int blankRows = 0;
double notEmpty = 1;
while (notEmpty > 0)
{
string aCellAddress = "A" + (rowIndex++).ToString();
Excel.Range row = excelApp.get_Range(aCellAddress, aCellAddress).EntireRow;
notEmpty = excelApp.WorksheetFunction.CountA(row);
if (notEmpty <= 0)
{
blankRows++;
}
}
but this is very time consuming process when file is large and minimum number of blank rows is there.
One thing that might help would be to find the last column that has data and last row that has data as to limit your search.
This is VBA code snippet, but could be easily transformed to C#:
'iterate through columns to determine which is longest to determine the highest row number.
For i = 1 To 16384 'number of columns in excel
'get the row
rowcount = ws.Cells(Rows.Count, i).End(xlUp).Row
'check to see if it's larger than what it is now, if it is, set the value of lRow.
If rowcount > lrow Then
lrow = rowcount
End If
Next
then use a similar loop to get the last row based on the last row, stepping through each row until the last one to get the last column with data.
You can use those values to limit the range that you're looking through. I'm not sure if it will be any faster, but it might help.
I have a DataGrid of variable dimensions dependent upon screen-res. I need to know how many rows are visible to the user. Here's my code:
uint VisibleRows = 0;
var TicketGrid = (DataGrid) MyWindow.FindName("TicketGrid");
foreach(var Item in TicketGrid.Items) {
var Row = (DataGridRow) TicketGrid.ItemContainerGenerator.ContainerFromItem(Item);
if(Row != null && Row.IsVisible) {
VisibleRows++;
}
}
I'm using the following code to test the vars:
MessageBox.Show(String.Format("{0} of {1} rows visible", VisibleRows, TicketGrid.Items.Count));
When there are no rows in the grid, it correctly shows 0 of 0 rows visible:
When there is 1 row in the grid, it correctly shows 1 of 1 rows visible:
When there are 9 rows in the grid, it correctly shows 9 of 9 rows visible:
The next row is "half-visible", so I'll count it showing 10 of 10 rows visible as correct:
However the next row to be added is apparently visible, incorrectly showing 11 of 11 rows visible:
Rows added after this are correct (bar the stray 1), e.g. 11 of 18 rows visible:
I can't just - 1, because it's only incorrect after a certain number have been added. I can't check > 10, because the dimensions are variable.
How can I fix this?
Here's what finally worked for me:
uint VisibleRows = 0;
var TicketGrid = (DataGrid) MyWindow.FindName("TicketGrid");
foreach(var Item in TicketGrid.Items) {
var Row = (DataGridRow) TicketGrid.ItemContainerGenerator.ContainerFromItem(Item);
if(Row != null) {
/*
This is the magic line! We measure the Y position of the Row, relative to
the TicketGrid, adding the Row's height. If it exceeds the height of the
TicketGrid, it ain't visible!
*/
if(Row.TransformToVisual(TicketGrid).Transform(new Point(0, 0)).Y + Row.ActualHeight >= TicketGrid.ActualHeight) {
break;
}
VisibleRows++;
}
}
Upto and including row 9 shows 9 of 9 visible. The "half-visible" row 10 results in 9 of 10 visible. It's actually better for my purposes for this not to count as a visible row, so this'll do for me! :)
Note: if you're reusing my code without using the break, any invisible rows after the offending row will throw a NullRefException.
I have a WPF window with a grid with 2 rows and some columns with text and buttons, then when I click a button the code adds some rows and populates them with random textblocks and images via for loops. For example, the method I call to add a TextBlock with text s in the (i,j) cell of the grid is
public void createTextBlock(int i, int j, string s)
{
TextBlock tb = new TextBlock();
//Properties
tb.Foreground = Brushes.Navy;
tb.FontFamily = new FontFamily("Century Gothic");
tb.FontSize = 16;
tb.FontWeight = FontWeights.UltraBold;
tb.TextWrapping = TextWrapping.Wrap;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.HorizontalAlignment = HorizontalAlignment.Center;
tb.Text = s;
//Add to the Grid
MyGrid.Children.Add(tb);
Grid.SetRow(tb, i);
Grid.SetColumn(tb, j);
}
and the method to add an image is similar. The problem is that when I click again, new textblocks and images are added above the old ones and I don't know how to update the content or clear it before adding another.
It is puzzling because the code (before adding rows) checks if the rows are more than 2, and if this is the case it clears all the exceeding rows:
if (MyGrid.RowDefinitions.Count > 2)
{
MyGrid.RowDefinitions.RemoveRange(2, MyGrid.RowDefinitions.Count-2);
}
but somehow this is not sufficient to clear their content... how can I do it?
EDIT (to clarify):
To add rows I use something like this (a little different because there is a switch call but it does not modify the essence)
public void createGrid(int n)
{
//remove rows if present
if (MyGrid.RowDefinitions.Count > 2)
{
MyGrid.RowDefinitions.RemoveRange(2, MyGrid.RowDefinitions.Count-2);
}
//permutation
int[] permutation = shuffle(deck.Count);
for (int i = 2; i < n + 2; i++)
{
RowDefinition row = new RowDefinition();
MyGrid.RowDefinitions.Add(row);
row.Height = new GridLength(200, GridUnitType.Pixel);
//add image
createImage(i, 0, deck[permutation[i - 2]].ImmPath);
//add textblock in center column with text chosen
//from a jagged array
createTextBlock(i, 1, value[0][i-2]);
//add textblock in right column
createTextBlock(i, 2, deck[permutation[i - 2]].Meaning);
}
So the idea is not to add new rows every time but to update the exsisting ones (or add them if needs be, createGrid can be called with different values for n). So I came up with the idea to wipe out the rows exceeding the first 2 (which contains the title and buttons) every time I call that method and add only the needed ones. This is the reason for the first check and RemoveRange.
Assuming you know the row and column of the control you want to remove you could do this
foreach (UIElement control in MyGrid.Children)
{
if (Grid.GetRow(control) == row && Grid.GetColumn(control) == col)
{
MyGrid.Children.Remove(control);
break;
}
}
The problem is this
It is puzzling because the code (before adding rows) checks if the
rows are more than 2, and if this is the case it clears all the
exceeding rows
If you are including items that you want to show below the current items, you need to increase the number of RowDefinitions instead of maintain the same.
I'm trying to display the table of m*n cells with some text in each cell, and the background colors of each cell could be different.
Am I right the dataGridView component could be used exactly for this purpose?
If yes, then how to make the dataGridView to contain more then just one empty row? Let's say I want it 5*5 cells and the cells could be empty.
You can add values to a DataGridView control in many ways: from a database, from a Collection (Array, DataTable, etc.), directly row by row, etc. In each cell you can put the (string) values you want, including ""/empty. Here you have a sample code to get some inspiration:
int count = 0;
int maxCount = 5;
do
{
count = count + 1;
//dataGridView1.Rows.Add("col1", "col2", "col3", "col4", "col5");
dataGridView1.Rows.Add(); //For adding empty rows, you can use this one
} while(count < maxCount);
dataGridView1[1, 2].Style.BackColor = Color.Yellow;
dataGridView1[3, 1].Style.BackColor = Color.Yellow;
dataGridView1[4, 4].Style.BackColor = Color.Yellow;
It takes dataGridView1 (a DataGridView with 5 columns added via "Design View"), adds 5 rows to it and colors the background of various cells.
i have a Grid and i have 4 rows and I need to update the 4th row based on the inputs in the 1st,2nd and 3rd row values .
Example :
1st when you enter 1 the total in the 4th row should be 1
when you enter 1 in 1st row and 2 in 2nd row the total shoud be 3 .
Should we use java script as these rows are in a grid when we hit a pop up on the page .
let me know if I am missing anything
This question has been already discussed in the IG forum at: http://www.infragistics.com/community/forums/t/77638.aspx
Here's what I wrote there:
You could handle the AfterCellUpdateHandler. It will fire after a
cell’s value has been changed so in it you could look through the cell
values and calculate the sum. After that you can change the last
cell’s value. For example:
function UltraWebGrid1_AfterCellUpdateHandler(gridName, cellId){
var cell = igtbl_getCellById(cellId);
var totalCell = cell.Row.getCellFromKey("Total");
var sum = 0;
for (var i = 1; i < cell.Row.cells.length-1; i++) {
sum += cell.Row.getCell(i).getValue();
}
cell.Row.getCellFromKey("Total").setValue(sum);
}
Please refer to the attached sample. In it if you change the value in
any of the cells the value of the related cell from the column “Total”
will be calculated based on the new values.
Let me know if you have any questions.
You can do something like
dataGridView1.Rows[0].Cells[0].Value = Convert.ToInt32(dataGridView1.Rows[1].Cells[0].Value) + Convert.ToInt32(dataGridView1.Rows[2].Cells[0].Value) ;
In the [ ], you will have to enter desired index of row or column.
You can use Unbound field
see this example Unbound field
here you can see unbound field of subtotal,SalesTax and Total and code done at cs side in InitializeRecord event.