Ultrawingrid - Select row based on unique value - c#

Is there a way to select a row in an ultrawingrid based on the value of one of its columns (ID column)? I have been trying to find out how to do this with little success.
I have a global variable that is the 'active ID' (i.e the ID that is currently being edited within the application - it is the ID that the system sees as being selected and active) - but sometimes the selected row of the grid and the 'selected ID' variable don't match. I need to make sure they are the same in order to prevent user confusion. I am hoping to call the following code inside a refresh() function...
Perhaps something like (kinda-pseudo-code-ish):
int index; // This could be any number
foreach (row r in grid)
{
if (row.cell["ID"].value = index)
grid.selectedindex = thisRow;
}
Am I thinking along the right lines? If so, what is the correct syntax? If not, how else should I do this?

Got it.
int index;
foreach (UltraGridRow row in grid.Rows)
{
if (Convert.ToInt32(row.Cells["ID"].Value) == index)
{
grid.ActiveRow = row;
break;
}
}
Works just how I needed it to - sorry for answering my own question ;)

Yes. You can use the FirstOrDefault function to find a row matching a criteria:
var row = ultraGrid1.Rows.FirstOrDefault(r => r.Cells["Id"].Value.ToString() == "1");
Now that you (potentially) have the row where the cell contains the value you'd like, you can activate it to select it:
if (row != null)
row.Activate();

If you are bound to a DataTable or a list that has the ability to find an item by key, you can use the GetRowWithListIndex method of the Rows collection to find the UltraGridRow.
For example the following will activate the row with a key of 5:
DataTable dt = this.ultraGrid1.DataSource as DataTable;
DataRow dr = dt.Rows.Find(5);
this.ultraGrid1.Rows.GetRowWithListIndex(dt.Rows.IndexOf(dr)).Activate();
If your list doesn't support finding an item by key, you could use linq to find the item in the list as well. There is an example of finding an item with link here.

If you have multiple bands you can use the following:
int index;
ultraGrid1.DisplayLayout.Bands.OfType<Infragistics.Win.UltraWinGrid.UltraGridBand>()
.SelectMany(s => s.GetRowEnumerator(Infragistics.Win.UltraWinGrid.GridRowType.DataRow)
.OfType<Infragistics.Win.UltraWinGrid.UltraGridRow>())
.Where(s => s.Cells.Exists("ID"))
.FirstOrDefault(s => (int)s.Cells["ID"].Value == index)?
.Activate();
Note: Null-conditional Operator (?) requires C# 6.0 or higher. Otherwise you have to check, if FirstOrDefault(...)!=null and activate it then.

Related

What is the best way to get the index of the datagridview row with the smallest integer value for a particular column

Could anyone tell me please what the best/most efficient way is to get the index of the row in a datagrid view that has the smallest integer value for a particular column.
I did this using a foreach loop to traverse the collection of rows and compare the respective value of each row and store the smallest. Each time I find a smaller value I update my "smallest" variable with that value. This works but I'm pretty sure there must be some lambda expression that does a better job. Could anyone help please?
This is the column containing the value:
dgvItems.Rows[i].Cells["col1"].Value
Many thanks.
the best way to do so is with LINQ queries,
LINQ is better looking, more readable and more efficient than for loops
you should use the DataGridView data source and not directly to the DataGridView data
DataTable dt = dgv.DataSource as DataTable;
MinRow: var result = dt.Rows.IndexOf(dt.AsEnumerable().OrderBy(x => x["col1"]).First());
MaxRow: var result1 = dt.Rows.IndexOf(dt.AsEnumerable().OrderByDescending(x => x["col1"]).First());
hope this could help you
I will help you for this one since you are not asking about using LINQ.
Lets do it the "usual" way..
First, declare a new List
List<int> columnValue = new List<int>();
we will Iterate through each row in the grid
foreach (DataGridViewRow row in myDataGrid.Rows)
{
if (null != row && null != row.Cells["col1"].Value)
{
//Add the value of columnValue to list
columnValue.Add(Convert.ToInt32(row.Cells[0].Value.ToString()));
}
}
and get the MIN. value from LIST
int result = columnValue.Min();
finally, get the index of the value we got from the LIST
int i = columnValue.IndexOf(result); //returns the Index from "result" var

Targeting a specific column in a DataRow

I'm trying to perform the C# equivalent of Select * where [columnname] = [value]. I began with a foreach loop to iterate through the table row by row, however I had forgotten that one cannot access a column via row.column["<colname>"].
How do I achieve this objective? Most of the examples I have seen target one specific row with the intention of casting it's value to a string, however my task is to move all entries with a value of DateTime == < DateTime.Today to an archived table.
Can I continue with the following code? Or am I approaching this in the wrong manner?
void archiveDates()
{
foreach (DataRow row in workingupdates.storageTable.Rows)
{
//target DateTime column here
}
}
You can use the Field extension method that is strongly typed and also supports nullable types. You have an overload for the index, name or the DataColumn(among others):
foreach (DataRow row in workingupdates.storageTable.Rows)
{
DateTime dt = row.Field<DateTime>("columnname");
}
If you instead want to find all rows where the date column has a specific value you can use Linq-To-DataTable:
var matchingDataRows = workingupdates.storageTable.AsEnumerable()
.Where(row => row.Field<DateTime>("columnname") == dateTimeVariable);
Now you can simply enumerate this query:
foreach (DataRow row in matchingDataRows)
{
// ...
}
Or create a collection like
a DataRow[] with matchingDataRows.ToArray() or
a List<DataRow> with matchingDataRows.ToList()
a new DataTable with matchingDataRows.CopyToDataTable()
Note that you have to add System.Linq; to the top of the file.

C# comboBox from dataGridView?

I want combobox with values from one cell datagridview. i try this, but don't work :( any ideas?
comboBox1.Items.Clear();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
comboBox1.Items.Add(row.Cells[2].Value.ToString());
}
The Value property is null, and throwing the exception when you call ToString() on it.
Check for null first:
if (row.Cells[2].Value != null)
comboBox1.Items.Add(row.Cells[2].Value.ToString());
Alternatively, use LINQ to iterate through the rows and populate the ComboBox:
comboBox1.Items.AddRange(
dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(x => x.Cells[2].Value != null)
.Select(x => x.Cells[2].Value.ToString())
.ToArray());
I think row.Cells[2].Value has NULL. Try
row.Cells[1].Value
The row.Cells[i] collection always starts at 0, so depending on how many columns you have, row.Cells[2] is actually the third column, and could be non existent. However, if that's the case, you'd like end up with a 'System.IndexOutOfRange' exception instead.
It's more likely that the cell doesn't have anything in it, or that the row doesn't even exist. Step through the debugger and see where the error is coming up.
Another, more specific way of handling this would be to specify the range by using a for loop instead:
// Rows.Count specifies the range explicitly - if you have 5 rows,
// if i <= 5, it will loop through until it increments to 6, then stop.
for(int i = 0; i <= dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows.Cells[2].Value != null)
comboBox1.Items.Add(dataGridView1.Rows.Cells[2].Value.ToString());
}

Clearing datagridview starting from the chosen row

I want to clear the datagridview starting from the row which user chose. I am trying a few ways to implement it, but they all generate some errors, now I have something like this:
foreach(DataGridViewRow row in this.dataGridView1.Rows)
{
if(row.Index >= odelementu - 1)
dataGridView1.Rows.RemoveAt(row.Index);
}
User need to choose from which row we should clear the datagridview and then click the button
odelementu //this variable represents the starting row
I don't know why the loop misses some rows. I would be grateful for any advices
It's because you modify the DataGridViewRowCollection in the foreach loop and make the index gotten becomes inexact. Try this instead:
while(dataGridView1.Rows.Count>=odelementu) {
dataGridView1.Rows.RemoveAt(odelementu-1);
}
public void RemoveRows()
{
var selectedrows = datagridview.SelectedRows.Cast<DataGridViewRow>();
if (selectedrows.Count() == 0)
return;
var fromIndex = selectedrows.Last().Index;
datagridview.Rows.Cast<DataGridViewRow>()
.Where(p=>p.Index > fromIndex)
.ToList()
.ForEach(p=>datagridview.Rows.Remove(p));
}

compare value property

how can I compare value property of item to datatable column called Value? Please help me with the syntax
if ((String)item.Value.IndexOf((string)results("value") Stringcomparison.CurrentCultureIgnoreCase) > -1)
{
returnItems.Add(item);
}
Your question and comment seem to be asking different things, but in both cases the answer is probably to unpick the big long line of code into explanatory variables:
string valueFromTable = currentRow["Value"].ToString();
bool itemValueContainsValueFromTable = item.Value.IndexOf(valueFromTable, StringComparison.CurrentCultureIgnoreCase) >= 0;
bool itemValueEqualsValueFromTable = item.Value.Equals(valueFromTable, StringComparison.CurrrentCultureIgnoreCase);
if (/* whichever of these you are interested in */)
{
returnItems.Add(item);
}
(ignoring error cases here, specifically if item.Value is null)
Note that to get a value from the DataTable you will need to pick a row. If you want to see if the item matches any row, then iterate over the rows (foreach (var row in table.Rows)).

Categories