c# - vacias - Encuentre una fila en dataGridView basada en columna y valor
seleccionar una celda de un datagridview c# (7)
Tengo un dataGridView que tiene 3 columnas: SystemId, FirstName, LastName que está enlazado usando la información de la base de datos. Me gustaría resaltar una cierta fila, que haría usando:
dataGridView1.Rows[????].Selected = true;
Sin embargo, el Id. De fila I no lo sabe y el bindingsource sigue cambiando, por lo que la fila 10 podría ser "John Smith" en una instancia pero no existir en otra (tengo un filtro que filtra la fuente según lo que ingresa el usuario, por lo que en "joh" daría todas las filas donde el nombre / apellido tiene "joh" en ellas, por lo tanto, mi lista puede ir de 50 nombres a 3 en un clic).
Quiero encontrar la manera de seleccionar una fila basada en SystemId y un número correspondiente. Puedo obtener la identificación del sistema usando el siguiente método:
systemId = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["SystemId"].Value.ToString();
Ahora solo necesito aplicarlo al selector de filas. Algo como dataGridView1.Columns ["SystemId"]. IndexOf (systemId} pero eso no funciona (ni existe ese método). Cualquier ayuda es muy apreciada.
Esto le dará el índice de fila de gridview para el valor:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if(row.Cells[1].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
O una consulta LINQ
int rowIndex = -1;
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
entonces puedes hacer:
dataGridView1.Rows[rowIndex].Selected = true;
Esto se basa en la respuesta anterior de Gordon: no todo es mi trabajo original. Lo que hice fue agregar un método más genérico a mi clase de utilidad estática.
public static int MatchingRowIndex(DataGridView dgv, string columnName, string searchValue)
{
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
if (dgv.Rows.Count > 0 && dgv.Columns.Count > 0 && dgv.Columns[columnName] != null)
{
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => r.Cells[columnName].Value.ToString().Equals(searchValue));
rowIndex = row.Index;
}
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
return rowIndex;
}
Entonces, en cualquier forma que quiera usarlo, llamo al método pasando DataGridView, nombre de columna y valor de búsqueda. Para simplificar, estoy convirtiendo todo en cadenas para la búsqueda, aunque sería bastante fácil agregar sobrecargas para especificar los tipos de datos.
private void UndeleteSectionInGrid(string sectionLetter)
{
int sectionRowIndex = UtilityMethods.MatchingRowIndex(dgvSections, "SectionLetter", sectionLetter);
dgvSections.Rows[sectionRowIndex].Cells["DeleteSection"].Value = false;
}
Las respuestas anteriores solo funcionan si AllowUserToAddRows
se establece en false
. Si esa propiedad se establece en true
, obtendrá una NullReferenceException
cuando el bucle o la consulta Linq intenten negociar la nueva fila. He modificado las dos respuestas aceptadas anteriormente para manejar AllowUserToAddRows = true
.
Respuesta de bucle:
String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
if (row.Cells["SystemId"].Value != null) // Need to check for null if new row is exposed
{
if(row.Cells["SystemId"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
break;
}
}
}
Respuesta LINQ:
int rowIndex = -1;
bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;
dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
DataGridViewRow row = dgv.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
.First();
rowIndex = row.Index;
dgv.AllowUserToAddRows = tempAllowUserToAddRows;
Los que usan WPF
for (int i = 0; i < dataGridName.Items.Count; i++)
{
string cellValue= ((DataRowView)dataGridName.Items[i]).Row["columnName"].ToString();
if (cellValue.Equals("Search_string")) // check the search_string is present in the row of ColumnName
{
object item = dataGridName.Items[i];
dataGridName.SelectedItem = item; // selecting the row of dataGridName
dataGridName.ScrollIntoView(item);
break;
}
}
si desea obtener los artículos de la fila seleccionados después de esto, el siguiente fragmento de código es útil
DataRowView drv = dataGridName.SelectedItem as DataRowView;
DataRow dr = drv.Row;
string item1= Convert.ToString(dr.ItemArray[0]);// get the first column value from selected row
string item2= Convert.ToString(dr.ItemArray[1]);// get the second column value from selected row
O puede usar así. Esto puede ser más rápido.
int iFindNo = 14;
int j = dataGridView1.Rows.Count-1;
int iRowIndex = -1;
for (int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count/2) +1; i++)
{
if (Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value) == iFindNo)
{
iRowIndex = i;
break;
}
if (Convert.ToInt32(dataGridView1.Rows[j].Cells[0].Value) == iFindNo)
{
iRowIndex = j;
break;
}
j--;
}
if (iRowIndex != -1)
MessageBox.Show("Index is " + iRowIndex.ToString());
else
MessageBox.Show("Index not found." );
Prueba esto:
string searchValue = textBox3.Text;
int rowIndex = -1;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["peseneli"].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
dataGridView1.CurrentCell = dataGridView1.Rows[rowIndex].Cells[0];
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Selected = true;
break;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
Si solo desea verificar si ese artículo existe:
IEnumerable<DataGridViewRow> rows = grdPdfs.Rows
.Cast<DataGridViewRow>()
.Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue));
if (rows.Count() == 0)
{
// Not Found
}
else
{
// Found
}