2

我用 DataTable 作为 DataSource 填充了 DataGridView。此 DataSource 有一列,其中包含注释。我将此列隐藏为要求的一部分,并添加了一个新的 DataGridVewLinkColumn,当​​单击该列时,用户将能够看到该评论。

我的问题是,当我通过单击 DataGridView 中的任何标题进行排序时,所有 DataGridViewLinkColumn 链接都会消失。我已在此 LinkColumn 中将 SortMode 设置为 Automatic,但似乎我需要做其他事情,因为只要我单击 Grid 中其他列的标题,链接就会消失。

任何人都知道如何确保在对 DataGridView 进行排序时,链接列得到相应的排序?

非常感谢

好的,我想通了。问题是因为我使用 DataTable 作为 DataSource 它已绑定到网格,并且无法向已绑定的网格源添加额外的列并期望它将与源绑定。为了解决这个问题,我只是修改了数据表。在数据表中添加额外的列,其中包含将成为 DataGridView 中的链接的字符串,并按照http://msdn.microsoft.com/en-us/library/bxt3k60s(v=vs.90 ) 中的建议以编程方式填充 DataGridView ).aspx

4

1 回答 1

0

Windows 窗体 DataGridView 控件中的列排序模式

对同时包含绑定列和未绑定列的 DataGridView 控件进行排序时,无法自动维护未绑定列中的值。要维护这些值,您必须通过将 VirtualMode 属性设置为 true 并处理 CellValueNeeded 和 CellValuePushed 事件来实现虚拟模式。

这有点复杂,所以最简单的解决方案是在 DataTable 中添加一个额外的列。

我将在下面留下一个示例以供将来参考。

要点是:

  • VirtualMode应该是真的
  • CellValueNeeded应正确处理以显示指定的单元格值。
  • ColumnHeaderMouseClick应该正确处理以按未绑定的列排序,并显示排序字形。

笔记:

  • 此示例中的 DataGridView 是只读的,以使事情变得简单。

此示例表单包含:

  • 一个类型化的数据集,具有(string), (string)DataTable1列: IDComment

    private DataSet1 dataSet1;
    
  • 一个绑定源:

    private BindingSource dataTable1BindingSource;
        .DataMember = "DataTable1";
        .DataSource = this.dataSet1;
    
  • 一个数据网格视图:

    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];
        }
    }
}
于 2014-07-29T04:53:47.793 回答