Как создать поля LookUp в DataGridView?
В моем DataGridView
Я показываю кучу столбцов из одной таблицы. В этой таблице у меня есть столбец, который указывает на элемент в другой таблице. Как вы уже догадались, я хочу отобразить в сетке в одном столбце текстовое значение из второй таблицы вместо ItemID. Я не мог найти правильный пример в сети, как это сделать.
Предположим, у меня есть две таблицы в базах данных:
Таблица пользователей:
UserID UserName UserWorkplaceID
1 Martin 1
2 John 1
3 Susannah 2
4 Jack 3
Рабочие места за столом:
WorkplaceID WorkplaceName
1 "Factory"
2 "Grocery"
3 "Airport"
У меня есть один нетипизированный набор данных dsUsers
один обязательный источник bsUsers
, и два DataAdapters
для заполнения набора данных (daUsers
, daWorkplaces
).
Код, который я выполняю:
daUsers.Fill(dsUsers);
daWorkplaces.Fill(dsUsers);
bsUsers.DataSource = dsUsers.Tables[0];
dgvUsers.DataSource = bsUsers;
На данный момент я вижу в моем dgvUsers
три столбца, UserID, UserName и UserWorkplaceID. Однако вместо UserWorkplaceID и значений 1,2,3 я бы хотел видеть "Фабрика", "Бакалея" и так далее...
Поэтому я добавил еще один столбец в dgvUsers
называется "WorkplaceName" и в моем коде я пытаюсь связать его с недавно созданным отношением:
dsUsers.Relations.Add("UsersWorkplaces", dsUsers.Tables[1].Columns["WorkplaceID"], dsUsers.Tables[0].Columns["UserWorkplaceID"]);
WorkplaceName.DataPropertyName = "UsersWorkplaces.WorkplaceName";
К сожалению, это не работает. Связь создается без ошибок, но поля в этом столбце остаются пустыми после запуска программы.
Что я делаю не так?
Я также хотел бы спросить о примере с комбинированным списком LookUp в DataGridView, который позволяет мне изменять UserWorkplaceID, но вместо числового значения будет отображаться значение tex, которое находится под WorkplaceName.
Спасибо за ваше время.
3 ответа
Я не знаю, можете ли вы сделать именно то, что вы хотите, что связывает DataGridView с двумя разными DataTable
экземпляры одновременно. Я не думаю, что DataGridView
класс поддерживает это - или, если это так, то это движение в стиле ниндзя, которого я не видел.
Согласно MSDN, лучше всего использовать CellFormatting
событие в DataGridView и проверьте, находится ли отформатированная ячейка в столбце поиска, тогда вы можете заменить свое значение из другой таблицы. Используйте несвязанный столбец для столбца WorkplaceName, скройте столбец UserWorkplaceID и затем реализуйте дескриптор события CellFormatting, чтобы найти значение в строке, например:
private void dgv_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
if (dgv.Columns[e.ColumnIndex].Name.Equals("WorkplaceName")
{
// Use helper method to get the string from lookup table
e.Value = GetWorkplaceNameLookupValue(
dataGridViewScanDetails.Rows[e.RowIndex].Cells["UserWorkplaceID"].Value);
}
}
Если вы видите много строк, это может повлиять на производительность, но, вероятно, это хороший способ заставить его работать.
Если вам это не нравится, возможно, воспользуйтесь DataTable.Merge()
метод, чтобы объединить вашу таблицу поиска в вашу основную таблицу. Беглый взгляд на одну из моих книг по ADO.NET показывает, что это должно сработать, хотя я не пробовал. Но я не уверен, что это слишком близко к предложенной ранее идее, которую вы сбили.
Что касается вашего второго вопроса о комбинированном списке поиска, вы должны действительно опубликовать его в отдельном вопросе, чтобы он получил должное внимание.
На мой взгляд, лучшим решением будет использовать тип столбца DataGridViewComboBoxColumn. Если вы сделаете это, вы должны заранее создать адаптер данных с поисковыми данными, а затем установить свойства DataSource, DataPropertyName, DisplayMember и ValueMember для DataGridViewComboBoxColumn. Вы также можете установить для свойства DisplayStyle значение Nothing, чтобы столбец выглядел как обычный столбец данных. Вот и все.
Вы могли бы заставить SQL делать эту работу. Используйте объединение, чтобы вернуть таблицу с именами рабочих мест вместо идентификаторов, вывести эту таблицу в набор данных и использовать ее вместо этого.
например.
SELECT A.UserID, A.UserName, B.WorkplaceID
FROM Users A
JOIN Workplaces B ON A.UserWorkplaceID = B.WorkplaceID
Затем используйте его вывод для заполнения dsUsers.