2

DataGridView に DataTable を DataSource として設定しました。この DataSource には、コメントを含む列があります。要件の一部としてこの列を非表示にし、クリックするとユーザーがそのコメントを表示できる新しい DataGridVewLinkColumn を追加しました。

私の問題は、DataGridView の任意のヘッダーをクリックして並べ替えると、すべての DataGridViewLinkColumn リンクが消えることです。この LinkColumn で SortMode を Automatic に設定しましたが、グリッド内の他の列のヘッダーをクリックするとすぐにリンクが消えるため、何か他のことをする必要があるようです。

DataGridView が並べ替えられたときに、リンク列がそれに応じて並べ替えられることを確認する方法を知っている人はいますか?

どうもありがとう

わかりました。問題は、グリッドにバインドされた DataSource として DataTable を使用し、既にバインドされているグリッド ソースに追加の列を追加する方法がなく、ソースとバインドされることを期待しているためです。この問題を解決するために、データ テーブルを変更しました。DataGridView のリンクとなる文字列を含む列をデータ テーブルに追加し、 http://msdn.microsoft.com/en-us/library/bxt3k60s(v= vs.90 .aspx

4

1 に答える 1

0

Windows フォーム DataGridView コントロールの列の並べ替えモード

バインドされた列とバインドされていない列の両方を含む DataGridView コントロールを並べ替えると、バインドされていない列の値を自動的に維持できません。これらの値を維持するには、VirtualMode プロパティを true に設定し、CellValueNeeded および CellValuePushed イベントを処理して、仮想モードを実装する必要があります。

これは少し複雑なので、最も簡単な解決策は、DataTable に列を追加することです。

今後の参考のために、以下に例を残しておきます。

ポイントは次のとおりです。

  • VirtualModetrueにする必要があります。
  • CellValueNeeded指定されたセル値を表示するには、適切に処理する必要があります。
  • ColumnHeaderMouseClickバインドされていない列で並べ替え、並べ替えグリフを表示するには、適切に処理する必要があります。

ノート:

  • この例の DataGridView は、簡単にするために読み取り専用になっています。

この例のフォームには次が含まれます。

  • (文字列)、 (文字列)DataTable1の列を持つ型指定された DataSet : IDComment

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