DataGridViewコントロールの列のサイズを自動的に変更し、ユーザーが同じグリッドの列のサイズを変更できるようにするにはどうすればよいですか?


109

Windowsフォーム(WPFではなくC#2.0)にDataGridViewコントロールを設定しています。

私の目標は、使用可能なすべての幅をセルできれいに埋めるグリッドを表示することです。つまり、右下の未使用(暗い灰色)領域はなく、含まれるデータに応じて各列のサイズを適切に設定しますが、ユーザーが任意の列のサイズを変更することもできます彼らの好みに。

各グリッドのAutoSizeModeをDataGridViewAutoSizeColumnMode.AllCellsに設定することでこれを実現しようとしています。ただし、グリッドの領域全体にデータがきちんと入力されるように、DataGridViewAutoSizeColumnMode.Fillに設定した列の1つを除きます。(ユーザーがこの列のサイズを変更しようとすると、水平方向のスペースが常に使用されるようにサイズが跳ね返ることは問題ありません。)

ただし、前述したように、一度読み込まれると、ユーザーが各自の要件に合わせて列のサイズを変更できるようにしたいと思います。各列にこれらのAutoSizeMode値を設定すると、ユーザーはそれらの列のサイズを変更できなくなるようです。

サイズ変更を許可するすべての列のAutoSizeModeを設定しないようにしましたが、セルに含まれるデータに応じて初期サイズが設定されません。データのロード後にグリッドのAutoSizeModeを「Not Set」に戻すと、同じ結果が発生します。

デフォルトの列幅の自動設定とユーザーによるサイズ変更を可能にする設定がここにありませんか、それともDataGridViewコントロールにデータを入力するときに使用する必要がある別のテクニックがありますか?


「Not Set」に設定しないでください。「None」に設定して 、サイズ変更が元に戻らないようにしてください 。c#、. net2.0でテスト済み
bh_earth0

回答:


132

このトリックは私にとってはうまくいきます:

grd.DataSource = DT;

//set autosize mode
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= grd.Columns.Count - 1; i++) {
    //store autosized widths
    int colw = grd.Columns[i].Width;
    //remove autosizing
    grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    //set width to calculated by autosize
    grd.Columns[i].Width = colw;
}

ここで何が起こるかというと、自動サイズを必要なモードに設定し、列ごとに自動サイズ計算から得た幅を保存し、自動サイズを削除して、幅を以前に保存した値に設定します。


1
AutoResizeColumnWidthsYetAllowUserResizingという名前のルーチンに同様のコードを挿入しました。これは、グリッドが最初に入力された後、およびユーザーがデータを編集した後に(つまり、グリッドのCellEndEditイベントから)呼び出されます。
DeveloperDan

5
これは素晴らしいコードです。「DataGridView1_DataSourceChanged」イベントに配置する必要があります。
user890332

1
私にはそれをgrd.Columns(i).Width = grd.Columns(i).Widthすることが既にトリックをするように思われる。こちらをご覧ください
Antonio

2
C#と同様ですが角かっこ付き dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
barlop

これは非常に遅くなったかもしれませんが、特定の行の内容に基づいてサイズを変更できますか?他の行のセルの幅に関係なく、最初の行のセルの内容に基づいてみましょうか?
Murtuza Husain

45

多分あなたは電話することができます

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

データソースを設定した後。幅を設定し、サイズを変更できます。

MSDN DataGridView.AutoResizeColumnsメソッド(DataGridViewAutoSizeColumnsMode)の詳細


2
なぜこの回答が注目されなくなったのかはわかりません。ずっときれい。セルのコンテンツの幅を一致させようとしている場合は、DataGridViewAutoSizeColumnsMode.AllCellsが少し良く機能します。
iwalkbarefoot

31
このソリューションを使用すると、次のエラーが発生します。「パラメーターautoSizeColumnModeはこの操作には無効です。NotSet、None、Fillにすることはできませんが、サイズ基準を示す必要があります。」。このdataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
itho 2012年

6
列のサイズを変更するときにセルの内容を無視するため、DataGridViewAutoSizeColumnMode.Fillを使用しても機能しません。
スチュアートヘルウィグ

この方法をで使用しましたDataGridViewAutoSizeColumnsMode.DisplayedCells。また、フォームデザイナでは、AutoSizeColumnsModeがNoneに設定されています。このメソッド呼び出しをDataGridViewのDataBindingCompleteイベントハンドラーで実行して、常に適切に(再)サイズ変更されるようにする必要がありました。
Daan

7
すべての賛成票を理解していません...これはまったく機能しません。MSDNドキュメントは明確です。これを行うと、autoSizeColumnsModeの値がNoneまたはFillの場合にArgumentExceptionが発生します。
ラリー

31

Miroslav ZadravecのコードのC#バージョン

for (int i = 0; i < dataGridView1.Columns.Count-1; i++)
{
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
    int colw = dataGridView1.Columns[i].Width;
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dataGridView1.Columns[i].Width = colw;
}

他人の評判を損なうことがないように、コミュニティウィキとして投稿されました


15

私のアプリケーションでは、設定しました

grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;

また、私は設定しました

grid.AllowUserToOrderColumns = true;
grid.AllowUserToResizeColumns = true;

これで、列の幅を変更したり、ユーザーが列を再配置したりできます。それは私にはかなりうまくいきます。

多分それはあなたのために働くでしょう。


グリッドのAutoSizeColumnsModeを「Fill」に設定すると、すべての列が同じ幅に設定されるようです。はい、列はサイズ変更可能ですが、最初の幅はすべて間違っています。コードで列幅を「手動で」設定する必要があるかもしれません。
スチュアートヘルヴィヒ2009年

DV- grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumn-> s <-Mode.Fill; (あなたはsを逃しました、それはあなたの行がコンパイルされないように左側と右側のColumsModeです)datagridviewを自動サイズ設定するためのコードはそのままで非常に面倒なので、少なくとも最初に答えを確認してください。それはあなたが書いた一番最初の行で、間違っています。
barlop

@barlop返信ありがとうございます。質問と回答を編集する権限があります。私のコードに間違いを見つけたら、自由に編集してください。
Jehof

12

データをグリッドに追加した後、各セルのデータの長さに応じて列を調整する次のコードを追加します

dataGrid1.AutoResizeColumns();            
dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

これが結果です

ここに画像の説明を入力してください


9

まあ、私はこれを次のように行いました:

dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvReport.AutoResizeColumns();
dgvReport.AllowUserToResizeColumns = true;
dgvReport.AllowUserToOrderColumns = true;

その特定の順序で。列はサイズ変更(拡張)され、ユーザーは後で列のサイズを変更できます。


6

私が質問を正しく理解した場合、必要なことを達成する簡単な方法があるはずです。コール dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

これでうまくいくはずです。ただし、DataGridViewコントロールにデータを入力した直後にこのメソッドを直接呼び出すことはできないため、1つの落とし穴があります。代わりに、VisibleChangedイベントのEventHandlerを追加して、そこでメソッドを呼び出す必要があります。


1
これにより、コンテンツに応じて列のサイズが変更されますが、使用可能なすべてのグリッドスペースが使用されるとは限りません。つまり、残っているスペースがあっても「埋める」ことはしません。
スチュアートヘルウィグ


4

質問の再開:
列の幅をコンテンツに適合させ(列全体で異なる方法を
使用)、ユーザーが列の幅を設定できるようにします...

ミロスラフ・ザドラベックの答えから発展して、私にとってうまくいったのは、自動計算column.Widthを使用して設定することでした... column.Width

foreach (DataGridViewColumn column in dataGridView.Columns)
{
    if (/*It's not your special column*/)
    {
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        column.Width = column.Width; //This is important, otherwise the following line will nullify your previous command
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
    }
}

//Now do the same using Fill instead of AllCells for your special column

これはDataGridViewこのようなトリックを使用して、がすでに作成されているときに動作するようにテストされています。


コードと同じように、foreachを使用することをお勧めします。ループの先頭に数学がない場合、より読みやすくなります。私はそのようにして、「column.Width = column.Width;」を実行しました。は興味深い。
グレッグバース2017

4

これは私にとって不思議でした:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

1
シンプルなソリューション!
Mark Kram

1
私のために働いすなわち、その後Noneに設定した場合にのみdataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
DOは-DO-新しい

3

これは、内容に応じてすべての列を自動調整し、指定された列を引き伸ばして残りの空のスペースを埋め、最後の列を将来のサイズ変更に合わせて埋めることで「ジャンプ」動作を防ぎます。

// autosize all columns according to their content
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
// make column 1 (or whatever) fill the empty space
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
// remove column 1 autosizing to prevent 'jumping' behaviour
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// let the last column fill the empty space when the grid or any column is resized (more natural/expected behaviour) 
dgv.Columns.GetLastColumn(DataGridViewElementStates.None, DataGridViewElementStates.None).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

古い答えだとは思いますが、事前にカラム数が分からない場合でも上手くいきます。
Nilo Paim 16

2

すべての列が自動サイズ調整されることを想定したMiroslav Zadravecのコードからの少しすっきりとしたC#コード

for (int i = 0; i < dgvProblems.Columns.Count; i++)
{
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    int colw = dgvProblems.Columns[i].Width;
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgvProblems.Columns[i].Width = colw;
}

2

Miroslav Zadravecのコードの別のバージョンですが、わずかに自動化されたユニバーサルなコードです。

    public Form1()
    {
        InitializeComponent();
        dataGridView1.DataSource = source;
        for (int i = 0; i < dataGridView1.Columns.Count - 1; i++) {
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }
        dataGridView1.Columns[dataGridView1.Columns.Count].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

    }

    void Form1Shown(object sender, EventArgs e)
    {
        for ( int i = 0; i < dataGridView1.Columns.Count; i++ )
        {
            int colw = dataGridView1.Columns[i].Width;
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            dataGridView1.Columns[i].Width = colw;
        }
    }

datagridvewフォームの初期化を入力し、両方の部分が存在する場合は何も変化しないため、2番目の部分を別のイベントに配置します。おそらくautosizeが幅を計算した後datagridviewで表示されるため、Form1()メソッドでは幅がデフォルトのままです。このメソッドの終了後、自動サイズ調整が行われ、その直後(フォームが表示されているとき)に、コードの2番目の部分(ここではForm1Shownイベント)によって幅を設定できます。これは魅力のように私のために働いています。


2

以下は、c#でのMiroslav Zadravecの回答の簡略化されたコードです。

CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
for (int i = 0; i < dataGridView1.Columns.Count; i++) dataGridView1.Columns[i].Width = dataGridView1.Columns[i].Width;
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

1

オブジェクトのFillWeightプロパティを設定しようとしましたDataGridViewColumnsか?

例えば:

this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.grid1.Columns[0].FillWeight = 1.5;

あなたの場合はうまくいくと思います。


1

シュナップルのバージョンから少し改善

int nLastColumn = dgv.Columns.Count - 1;
for (int i = 0; i < dgv.Columns.Count; i++)
{
    if (nLastColumn == i)
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    else
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
}

for (int i = 0; i < dgv.Columns.Count; i++)
{
    int colw = dgv.Columns[i].Width;
    dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgv.Columns[i].Width = colw;
}


1

列の幅をコンテンツに合わせて設定しました。次のステートメントを使用しましたが、問題は解決しました。

最初の一歩 :

RadGridViewName.AutoSize = true;

第二段階 :

// This mode  fit in the header text and column data for all visible rows. 
this.grdSpec.MasterTemplate.BestFitColumns();

3番目のステップ:

for (int i = 0; i < grdSpec.Columns.Count; i++) 
{
    // The column width adjusts to fit the contents all cells in the control.
    grdSpec.Columns[i].AutoSizeMode = BestFitColumnMode.AllCells; 
}

1
foreach (DataGridViewColumn c in dataGridView.Columns)
    c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);

これは、dataGridViewが表示されているかどうかに関係なく機能します(つまり、クラスコンストラクターから呼び出された場合でも)。

同じ方法ですが、を使用するとDataGridViewAutoSizeColumnMode.DisplayedCells、上記のケースでは明らかな理由で失敗します-セルはまだ表示されていません!明らかでない理由により、AutoResizeColumnsこの場合も失敗します。


0

たとえば、データソースをデータテーブルにバインドする場合、バインドの完了後にプロパティを設定する必要があります。

        private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.AutoResizeColumns();
            dgv.AllowUserToResizeColumns = true;
        }

0
  • 反復処理する上記の溶液(のおかげでDataGridView.Columns、変更AutoSizeMode有効なもの、コレクト幅の値へと変更後のバックそれを設定AutoSizeModeしますDataGridViewAutoSizeColumnMode.None)。
  • 私はそれで苦労し、そしてそれは、クラスのコンストラクタまたは任意の行の前から呼び出されたとき、それは動作しません気づきましたForm.Show()Form.ShowDialog()。だから私はこのコードスニペットをForm.Shownイベントに入れてこれは私のために働きます。
  • 私の変換されたコードは、DataGridView.AutoSizeColumnsMode以前に設定されたものに関係DataGridViewColumn.GetPreferredWidth()なくDataGridViewColumn.AutoSizeMode、幅の値を変更してすぐに設定する代わりに使用し、次にDataGridView.AutoSizeColumnsMode一度変更します。

    private void form_Shown(object sender, EventArgs e)
    {
            foreach (DataGridViewColumn c in dataGridView.Columns)
                c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true);
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
    }
  • 必ず設定してください

            dataGridView.AllowUserToResizeColumns = true;
  • これがフォームが表示された後にのみ機能する理由はわかりません。


0

私はこれをVBで行う必要があり、モジュールに配置したメソッドに分割することを好みました。必要に応じて、Fill列を別のByRefパラメータとして追加できます。

''' <summary>
''' Makes all columns in a DataGridView autosize based on displayed cells,
''' while leaving the column widths user-adjustable.
''' </summary>
''' <param name="dgv">A DataGridView to adjust</param>
Friend Sub MakeAdjustableAutoSizedGridCols(ByRef dgv As DataGridView)
    Dim width As Integer

    For Each col As DataGridViewColumn In dgv.Columns
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
        width = col.Width
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        col.Width = width
    Next
    dgv.AllowUserToResizeColumns = True
End Sub

0

あなたはこのようなことをすることができます:

   grd.DataSource = getDataSource();

    if (grd.ColumnCount > 1)
    {
        for (int i = 0; i < grd.ColumnCount-1; i++)
            grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

        grd.Columns[grd.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }

    if (grd.ColumnCount==1)
        grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

最後の列がグリッドを埋める以外は、すべての列がコンテンツに適応します。


0

$ arrayがPSCustomObjectのコンテンツであるため、これは機能します。

$dataGridView1.DataSource=[collections.arraylist]($array)
$dataGridView1.Columns | Foreach-Object{$_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.