【问题标题】:How make a DataGridVewLinkColumn sort with the rest of the DataGridView如何使 DataGridViewLinkColumn 与 DataGridView 的其余部分一起排序
【发布时间】:2014-09-19 15:46:05
【问题描述】:

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

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

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

非常感谢

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

【问题讨论】:

    标签: c# winforms sorting datagridviewlinkcolumn


    【解决方案1】:

    Column Sort Modes in the Windows Forms DataGridView Control

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

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

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

    要点是:

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

    注意:

    • 为了简单起见,本示例中的 DataGridView 是只读的。

    此示例表单包含:

    • 一个类型化的数据集,它有 DataTable1ID(string)、Comment(string) 的列:

      private DataSet1 dataSet1;
      
    • 一个绑定源:

      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];
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      相关资源
      最近更新 更多