Как установить выбранную строку в ASP.NET GridView на основе DataKey?
Я хочу что-то похожее на следующий псевдокод:
myGridView.SelectedIndex = myGridView.DataKeys.IndexOf("mySpecificKey");
Я провел исследование Intellisense, но не нашел очевидного способа сделать это. Я хотел бы установить SelectedIndex в -1, если DataKey не был найден.
9 ответов
Я закончил с
For n As Integer = 0 To myGridView.DataKeys.Count - 1
If myGridView.DataKeys(n).Value = myKeyObj Then
myGridView.SelectedIndex = n
End If
Next
Это работает, и это приятно и коротко:
int MyId = 22;
foreach (GridViewRow gvRow in gridview1.Rows)
{
if ((int)gridview1.DataKeys[gvRow.DataItemIndex].Value == MyId)
{
gridview1.SelectedIndex = gvRow.DataItemIndex;
break;
}
}
Рассматривали ли вы подход Linq?
Использование:
GridView1.SelectedIndex = GridView1.DataKeys.IndexOf(id);
Код:
public static class WebControlsEx
{
public static int IndexOf(this DataKeyArray dataKeyArray, object value)
{
if (dataKeyArray.Count < 1) throw new InvalidOperationException("DataKeyArray contains no elements.");
var keys = dataKeyArray.Cast<DataKey>().ToList();
var key = keys.SingleOrDefault(k => k.Value.Equals(value));
if (key == null) return -1;
return keys.IndexOf(key);
}
}
Ваш метод выше ищет только текущую страницу GridView, если подкачка включена. Чтобы выполнить поиск по всему GridView, вам нужно изучить его DataSource и использовать его для получения соответствующих значений.
В моем случае мне нужно было дать пользователям быстрый способ поиска определенного клиента, поэтому я добавил поле со списком с поддержкой AJAX и OnSelectedIndexChanged, я использовал это, чтобы найти соответствующую строку GridView и выбрать ее:
Dim i As Integer, DataSetIndex As Integer
Dim SelectedRowIndex As Integer
Dim dv As DataView = ObjectDataSourceClients.Select
Dim dt As DataTable = dv.ToTable
For i = 0 To dt.Rows.Count - 1
If dt.Rows(i)("Client_ID") = ComboBoxClientSearch.SelectedValue Then
DataSetIndex = i
Exit For
End If
Next
GridViewAllClients.PageIndex = DataSetIndex \ GridViewAllClients.PageSize
SelectedRowIndex = DataSetIndex - (GridViewAllClients.PageSize * GridViewAllClients.PageIndex)
GridViewAllClients.SelectedIndex = SelectedRowIndex
GridViewAllClients.DataBind()
Хорошо, большинство из них не правы. Фил единственный, кто работает. Ответ не работает. Проблема с ответом Фила состоит в том, что он привязан к SQL DataTable в asp.net, который никто не использует. Ну, некоторые делают, но когда вы начинаете использовать шаблоны проектирования, это отбрасывается.
Мой пример детализирует итерацию построчно и переключение индекса страницы и перепривязки. Я не смог найти фактическое свойство DataSource, потому что оно связано с элементом управления LinqDataSource, и я не могу добраться до фактических данных. И поиск в DataSource, вероятно, не будет работать в любом случае, потому что у вас есть поиск, сортировка и т. Д., Чтобы изменить данные и получить их фактический индекс строки, а не индекс сетки (или другого элемента управления).
Я использовал скрытый asp:HiddenControl, чтобы сохранить значение, потому что функция jQuery фактически выполняет обратную передачу. grdLocations это вид сетки
grdLocations.SelectedIndex = -1;
bool found = false;
int index = 0;
int pageIndex = 0;
for (int i = 0; i < grdLocations.PageCount; i++)
{
for (index = 0; index < grdLocations.DataKeys.Count; index++)
{
if (Convert.ToInt32(grdLocations.DataKeys[index].Value.ToString()) == Convert.ToInt32(hidCurrentRigId.Value))
{
found = true;
break;
}
}
if (found)
break;
pageIndex++;
grdLocations.PageIndex = pageIndex;
grdLocations.DataBind();
}
if (found)
{
grdLocations.PageIndex = pageIndex;
grdLocations.SelectedIndex = index;
}
Это будет повторять каждую страницу в виде сетки и выбирать правильный ключ данных.
Теперь, чтобы добавить, если вы хотите самый простой способ найти страницу, основанную на строке, используйте эту математику в этом примере консольного приложения. Это делает это действительно простым
class Program
{
static void Main(string[] args)
{
int rowIndex = 27;
int pageCount = 7;
int currentPage = 3;
int pageSize = 10;
Console.WriteLine("Page = " + (rowIndex / pageSize).ToString());
Console.WriteLine("Row = " + ( rowIndex % pageSize).ToString());
Console.ReadLine();
}
}
Надеюсь, это кому-нибудь поможет.
Попробуйте этот подход Linq:
grdMyGrid.SelectedIndex = grdMyGrid.DataKeys.OfType<DataKey>().ToList<DataKey>().FindIndex(dk => (string)dk.Value == "myKey");
//grab the current datakeyValue
int orderID = (int)this.GridView1.SelectedDataKey.Value;
//do something
gridView.databind();
//set back the selected row int the gridView
for (int i = 0; i <= this.GridView1.DataKeys.Count - 1; i++)
{
if ((int)GridView1.DataKeys[i].Value == orderID)
{
this.GridView1.SelectedIndex = i;
}
}
Поместите что-то вроде этого в ваше событие GridView_RowDataBound():
Dim p As Catalog.Product = CType(e.Row.DataItem, Catalog.Product)
If p IsNot Nothing Then
If p.Bvin = MySpecificID Then
e.Row.RowState = DataControlRowState.Selected
End If
End If
В этом примере мы связываем GridView с коллекцией пользовательских объектов типа Catalog.Product, а DataKey называется Bvin - вам нужно будет настроить тип данных и имя ключа в зависимости от того, к чему вы привязываете.
Обратите внимание, что это событие уже выполняется один раз для каждой строки, поэтому нет необходимости повторять цикл. Однако следует позаботиться о том, чтобы такие вещи, как доступ к данным, не повторялись более одного раза.
По сути, если у вас уже есть экземпляр GridViewRow, то сделайте это:
gridView.SelectedIndex = gridViewRowToBeSelected.RowIndex;