Windowsフォーム(WPFではなくC#2.0)にDataGridViewコントロールを設定しています。
私の目標は、利用可能なすべての幅をセルできれいに埋めるグリッドを表示することです。つまり、右下に未使用(暗い灰色)の領域がなく、含まれるデータに応じて各列のサイズを適切に調整し、 しかし また、ユーザーは任意の列のサイズを好みに合わせて変更できます。
各列のAutoSizeModeをDataGridViewAutoSizeColumnMode.AllCellsに設定することでこれを達成しようとしていますが、DataGridViewAutoSizeColumnMode.Fillに設定した列の1つを除きますグリッドの領域全体がきれいにデータで満たされています。 (ユーザーがこの列のサイズを変更しようとすると、常に水平スペースが使用されるサイズに戻ることを気にしません。)
ただし、前述したように、一度ロードすると、ユーザーが自分の要件に合わせて列のサイズを変更できるようにします。各列にこれらのAutoSizeMode値を設定すると、ユーザーはその後、それらの列のサイズを変更できないように見えます。
すべての列のAutoSizeModeを設定しないようにしましたが、サイズ変更が可能ですが、セルに含まれるデータに応じて初期サイズが設定されません。データをロードした後にグリッドのAutoSizeModeを「未設定」に戻すと、同じ結果が発生します。
デフォルトの列幅の自動設定とユーザーのサイズ変更を許可する設定がありませんか、DataGridViewコントロールを設定するときに使用する必要がある別のテクニックがありますか?
このトリックは私のために働く:
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;
}
ここで起こることは、必要なモードに自動サイズを設定し、自動サイズ計算から取得した幅を列ごとに保存し、自動サイズを削除して、以前に保存した値に幅を設定することです。
たぶんあなたは電話することができます
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);
データソースを設定した後。幅を設定し、サイズ変更を許可します。
MSDNの詳細 DataGridView.AutoResizeColumnsメソッド(DataGridViewAutoSizeColumnsMode) 。
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;
}
コミュニティWikiとして投稿され、他の人の評判を失いません。
私のアプリケーションでは、私が設定しました
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
また、私は
grid.AllowUserToOrderColumns = true;
grid.AllowUserToResizeColumns = true;
これで、列の幅を変更でき、ユーザーが列を再配置できます。それは私にはかなりうまくいきます。
たぶんそれはあなたのために働くでしょう。
データをグリッドに追加した後、各セルのデータの長さに応じて列を調整する次のコードを追加します
dataGrid1.AutoResizeColumns();
dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
結果はこちら
まあ、私はこれを次のようにした:
dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvReport.AutoResizeColumns();
dgvReport.AllowUserToResizeColumns = true;
dgvReport.AllowUserToOrderColumns = true;
その特定の順序で。列はサイズ変更(拡張)され、ユーザーは後で列のサイズを変更できます。
質問を正しく理解できたなら、あなたが必要とすることを達成する簡単な方法があるはずです。 dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
を呼び出します
これでうまくいくはずです。ただし、DataGridViewコントロールにデータを入力した後にこのメソッドを直接呼び出すことはできないため、落とし穴が1つあります。代わりに、VisibleChangedイベントにEventHandlerを追加し、そこでメソッドを呼び出す必要があります。
質問の再開:
列の幅をコンテンツに合わせます(列全体で異なる方法を使用)。
その後、ユーザーが列幅を設定できるようにします...
Miroslav Zadravec's answer から開発しました。私にとっては、すぐに自動計算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
これは、 this のようなトリックを使用して、DataGridView
がすでに作成されている場合に動作することがテストされています。
これは私にとって不思議でした:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
Miroslav Zadravecのc#での答えの簡単なコードを次に示します。
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;
単純な2行のコードでうまくいきます。
dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
すべての列が自動サイズ調整されることを前提とする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;
}
これにより、すべての列がその内容に応じて自動調整され、指定された列が引き伸ばされて残りの空のスペースが埋められます。
// 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;
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
を入力し、両方の部分が存在する場合、おそらく自動サイズがdatagridview
が表示された後に幅を計算するため、2番目の部分を別のイベントに入れます。したがって、幅はForm1()
メソッドのデフォルトのままです。このメソッドの終了後、autosizeがトリックを実行し、その後すぐに(フォームが表示されている場合)コードの2番目の部分(ここではForm1Shown
イベント)で幅を設定できます。これは私にとって魅力的です。
dataGridView1.AutoResizeColumns();
内容に合わせて設定された列幅は、私は以下のステートメントを使用しました、それは私の問題を解決しました。
最初の一歩 :
RadGridViewName.AutoSize = true;
第二段階 :
// This mode fit in the header text and column data for all visible rows.
this.grdSpec.MasterTemplate.BestFitColumns();
第三段階:
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;
}
シュナップルのバージョンから少し改善
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;
}
FillWeight
オブジェクトのDataGridViewColumns
プロパティを設定しようとしましたか?
例えば:
this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.grid1.Columns[0].FillWeight = 1.5;
あなたの場合にはうまくいくと思います。
DataGridView.Columns
を反復処理するには、AutoSizeMode
を有効な値に変更し、幅の値を収集して、AutoSizeMode
をDataGridViewAutoSizeColumnMode.None
に変更してから元に戻します)。Form.Show()
またはForm.ShowDialog()
の前の行から呼び出されたときはいつでも機能しないことに気付きました。そのため、このコードスニペットをForm.Shown
イベントに配置しましたが、これはうまくいきます。私が変換したコードは、以前に設定したDataGridView.AutoSizeColumnsMode
に関係なく、DataGridViewColumn.AutoSizeMode
を変更する代わりにDataGridViewColumn.GetPreferredWidth()
を使用し、すぐに幅の値を設定してから、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;
フォームが表示された後にのみこれが機能する理由はわかりません。
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
foreach (DataGridViewColumn c in dataGridView.Columns)
c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);
これは、dataGridView
が表示されているかどうかに関係なく機能します(クラスコンストラクターから呼び出された場合でも)。
同じ方法ですが、DataGridViewAutoSizeColumnMode.DisplayedCells
を使用すると、明らかな理由で上記のケースで失敗します-セルがまだ表示されていません!何らかの明白でない理由で、AutoResizeColumns
もこの場合失敗します。
次のようなことができます:
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;
最後の列がグリッドを埋める以外は、すべての列がコンテンツに適応します。
たとえば、データソースをデータテーブルにバインドする場合、バインドの完了後にプロパティを設定する必要があります。
private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgv.AutoResizeColumns();
dgv.AllowUserToResizeColumns = true;
}