Как сделать сортировку DataGridVewLinkColumn с остальной частью DataGridView
Я заполнил DataGridView DataTable в качестве источника данных. Этот источник данных имеет столбец с комментариями. Я скрываю этот столбец как часть требований и добавляю новый DataGridVewLinkColumn, чтобы при нажатии на него пользователь мог видеть этот комментарий.
Моя проблема заключается в том, что, когда я сортирую, щелкая любой заголовок в DataGridView, все ссылки DataGridViewLinkColumn исчезают. Я установил SortMode на Automatic в этом LinkColumn, но мне кажется, что мне нужно сделать что-то еще, потому что, как только я нажимаю на заголовки из других столбцов в Grid, ссылки исчезают.
Кто-нибудь знает, как я могу убедиться, что при сортировке DataGridView столбец ссылок сортируется соответствующим образом?
Большое спасибо
ОК, я понял это. Проблема заключается в том, что я использовал DataTable в качестве источника данных, он был привязан к сетке, и нет никакого способа добавить дополнительный столбец в источник сетки, который уже связан, и ожидать, что он будет привязан к источнику. Чтобы решить эту проблему, я просто изменил таблицу данных. Добавьте дополнительный столбец в таблицу данных со строками, которые будут ссылками в DataGridView, и заполняйте DataGridView программно, как рекомендуется в http://msdn.microsoft.com/en-us/library/bxt3k60s(v=vs.90).aspx
1 ответ
Режимы сортировки столбцов в элементе управления Windows Forms DataGridView
При сортировке элемента управления DataGridView, содержащего как связанные, так и несвязанные столбцы, значения в несвязанных столбцах не могут поддерживаться автоматически. Чтобы сохранить эти значения, вы должны реализовать виртуальный режим, установив для свойства VirtualMode значение true и обработав события CellValueNeeded и CellValuePressed.
Это немного сложно, поэтому самое простое решение - добавить дополнительный столбец в DataTable.
Я оставлю пример ниже для дальнейшего использования.
Очки:
VirtualMode
должно быть правдой.CellValueNeeded
должны быть обработаны правильно, чтобы показать указанные значения ячеек.ColumnHeaderMouseClick
должен обрабатываться правильно, чтобы сортировать по несвязанным столбцам и показывать глифы сортировки.
Замечания:
- DataGridView в этом примере предназначен только для чтения, чтобы упростить задачу.
Этот пример формы содержит:
Типизированный DataSet, который имеет
DataTable1
с колоннамиID
(Строка),Comment
(Строка):private DataSet1 dataSet1;
BindingSource:
private BindingSource dataTable1BindingSource; .DataMember = "DataTable1"; .DataSource = this.dataSet1;
DataGridView:
private DataGridView dataTable1DataGridView; .DataSource = this.dataTable1BindingSource; .VirtualMode = true; .CellValueNeeded += this.dataTable1DataGridView_CellValueNeeded; .ColumnHeaderMouseClick += this.dataTable1DataGridView_ColumnHeaderMouseClick; .ReadOnly = true; .AllowUserToAddRows = false; .AllowUserToDeleteRows = false;
Его столбцы:
private DataGridViewTextBoxColumn iDDataGridViewTextBoxColumn; // bound column private DataGridViewTextBoxColumn commentDataGridViewTextBoxColumn; // bound column private DataGridViewLinkColumn linkColumn; // unbound column .SortMode = DataGridViewColumnSortMode.Automatic;
И здесь идет код:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Hold the link texts, in a dictinary
// keyed by ID (= unique key in DataTable1), to be bound to each row.
private SortedDictionary<string, string> _linkTexts
= new SortedDictionary<string, string>();
private void Form1_Load(object sender, EventArgs e)
{
// Bound data sample
this.dataSet1.DataTable1.AddDataTable1Row("1", "Comment1");
this.dataSet1.DataTable1.AddDataTable1Row("2", "Comment2");
this.dataSet1.DataTable1.AddDataTable1Row("3", "Comment3");
// Unbound data sample
this._linkTexts.Add("1", "linkA");
this._linkTexts.Add("2", "linkC");
this._linkTexts.Add("3", "linkB");
}
// Handles ColumnHeaderMouseClick to do custom sort.
private void dataTable1DataGridView_ColumnHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
// When the unbound column header is clicked,
if (e.ColumnIndex == this.linkColumn.Index)
{
// Create a new DataView sorted by the link text
// with toggling the sort order.
DataView newView;
switch (this.linkColumn.HeaderCell.SortGlyphDirection)
{
case SortOrder.None:
case SortOrder.Descending:
this.linkColumn.HeaderCell.SortGlyphDirection
= SortOrder.Ascending;
newView = this.dataSet1.DataTable1
.OrderBy(row => this._linkTexts[row.ID])
.AsDataView();
break;
default:
this.linkColumn.HeaderCell.SortGlyphDirection
= SortOrder.Descending;
newView = this.dataSet1.DataTable1
.OrderByDescending(row => this._linkTexts[row.ID])
.AsDataView();
break;
}
// Set it as DataSource.
this.dataTable1BindingSource.DataSource = newView;
// Clear sort glyphs on the other column headers.
foreach (DataGridViewColumn col
in this.dataTable1DataGridView.Columns)
{
if (col != this.linkColumn)
col.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
// The bound column header is clicked,
else
{
// Sorting has done automatically.
// Reset the sort glyph on the unbound column.
this.linkColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
// Handles CellValueNeeded to show cell values in virtual mode.
private void dataTable1DataGridView_CellValueNeeded(
object sender, DataGridViewCellValueEventArgs e)
{
// Extract the bound row from the current data view.
DataSet1.DataTable1Row row
= (this.dataTable1BindingSource[e.RowIndex] as DataRowView)
.Row as DataSet1.DataTable1Row;
// For the unbound column,
if (e.ColumnIndex == this.linkColumn.Index)
{
if (row.IsIDNull())
e.Value = DBNull.Value;
else
// get the value from the dictionary.
e.Value = this._linkTexts[row.ID];
}
// For the bound columns,
else
{
// get the value from the data source.
string propName = this.dataTable1DataGridView
.Columns[e.ColumnIndex].DataPropertyName;
e.Value = row[propName];
}
}
}