IT박스

DataGridView 컨트롤의 열 크기를 자동으로 조정하고 사용자가 동일한 그리드의 열 크기를 조정할 수 있도록하는 방법은 무엇입니까?

itboxs 2020. 8. 11. 08:10
반응형

DataGridView 컨트롤의 열 크기를 자동으로 조정하고 사용자가 동일한 그리드의 열 크기를 조정할 수 있도록하는 방법은 무엇입니까?


Windows Form에 DataGridView 컨트롤을 채우고 있습니다 (WPF가 아닌 C # 2.0).

내 목표는 사용 가능한 모든 너비를 셀로 깔끔하게 채우는 그리드를 표시하는 것입니다. 즉, 오른쪽 아래에 사용되지 않는 (진한 회색) 영역이없고 포함 된 데이터에 따라 각 열의 크기를 적절하게 조정 하지만 사용자가 모든 열의 크기를 조정할 수 있습니다. 그들의 취향에.

그리드의 전체 영역이 데이터로 깔끔하게 채워지 도록 DataGridViewAutoSizeColumnMode.Fill설정 한 열 중 하나를 제외하고 각 열의 AutoSizeMode를 DataGridViewAutoSizeColumnMode.AllCells 로 설정하여이를 달성하려고합니다 . (사용자가이 열의 크기를 조정하려고하면 항상 수평 공간이 사용되도록하는 크기로 다시 돌아 간다는 점에 신경 쓰지 않습니다.)

그러나 내가 언급했듯이 일단로드되면 사용자가 자신의 요구 사항에 맞게 열의 크기를 조정할 수 있도록하고 싶습니다. 각 열에 대해 이러한 AutoSizeMode 값을 설정하면 사용자가 해당 열의 크기를 조정할 수없는 것처럼 보입니다.

크기 조정을 허용하는 모든 열의 AutoSizeMode를 설정하지 않았지만 셀에 포함 된 데이터에 따라 초기 크기를 설정하지 않았습니다. 데이터를로드 한 후 그리드의 AutoSizeMode를 "Not Set"로 다시 변경할 때 동일한 결과가 발생합니다.

기본 열 너비 및 사용자 크기 조정의 자동 설정을 허용하는 여기에 누락 된 설정이 있습니까? 아니면 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 코드의 AC # 버전

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

다른 사람의 평판을 훼손하지 않도록 커뮤니티 위키로 게시


내 응용 프로그램에서 설정했습니다.

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

또한, 나는

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

이제 열 너비를 변경할 수 있으며 사용자가 열을 재정렬 할 수 있습니다. 그것은 나를 위해 꽤 잘 작동합니다.

아마도 그것은 당신을 위해 일할 것입니다.


그리드에 데이터를 추가 한 후 각 셀의 데이터 길이에 따라 열을 조정하는 다음 코드를 추가합니다.

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

결과는 다음과 같습니다.

enter image description here


글쎄, 나는 이것을 이렇게했다.

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

그 특정 순서로. 열의 크기가 조정 (확장)되고 사용자는 나중에 열의 크기를 조정할 수 있습니다.


질문을 올바르게 이해했다면 필요한 작업을 더 쉽게 수행 할 수있는 방법이있을 것입니다. 요구dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

그게 트릭을해야합니다. 그러나 DataGridView 컨트롤을 채운 후이 메서드를 직접 호출 할 수 없기 때문에 한 가지 함정이 있습니다. 대신 VisibleChanged 이벤트에 대한 EventHandler를 추가하고 거기에서 메서드를 호출해야합니다.


질문 재개 :
열 너비가 콘텐츠에 맞게 조정되도록하고 (열 전체에 다른 방법으로)
사용자가 열 너비를 설정할 수 있도록합니다.

Miroslav Zadravec의 대답 에서 개발 중 , 저에게 효과가 있었던 것은 즉시 자동 계산 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같은 트릭을 사용 하여이 이미 생성 되었을 때 작동하도록 테스트되었습니다 .


이것은 저에게 놀라운 일이었습니다.

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

간단한 두 줄의 코드가 저에게 효과적입니다.

dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();

Slightly neater C# code from Miroslav Zadravec's code assuming all columns are to be autosized

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

This autofits all columns according to their content, fills the remaining empty space by stretching a specified column and prevents the 'jumping' behaviour by setting the last column to fill for any future resizing.

// 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;

Another version of Miroslav Zadravec's code, but slightly more automated and universal:

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

I put second part into separate event, because I fill datagridvew in initialization of form and if both parts are there, nothing is changing, because probably autosize calculates widths after datagridview is displayed, so the widths are still default in Form1() method. After finishing this method, autosize does its trick and immediately after that (when form is shown) we can set the widths by second part of the code (here in Form1Shown event). This is working for me like a charm.


Here's a simplified code for Miroslav Zadravec's answer in 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;

Did you try to set up the FillWeight property of your DataGridViewColumns object?

For example:

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

I think it should work in your case.


A little improvement from Schnapple's version

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

dataGridView1.AutoResizeColumns();


The column widths set to fit its content I have used the bellow statement, It resolved my issue.

First Step :

RadGridViewName.AutoSize = true;

Second Step :

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

Third Step :

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

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

This should work whether the dataGridView has been displayed or not (i.e. even if called from the class constructor).

The same method, but with DataGridViewAutoSizeColumnMode.DisplayedCells, fails in the above case for the obvious reason - no cell has been displayed yet! For some non-obvious reason, AutoResizeColumns also fails in this case.


If you bind your datasource to a datatable for example, you need to set the properties after the binding is done:

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

  • Thanks for the solution above (To iterate through the DataGridView.Columns, change AutoSizeMode to a valid one, collect width value and set it back after change AutoSizeMode to DataGridViewAutoSizeColumnMode.None).
  • I struggled with it, and noticed it won't work whenever it is called from the class constructor or any line before Form.Show() or Form.ShowDialog(). So I put this code snippet in the Form.Shown event and this works for me.
  • My transformed code, reguardless of whatever DataGridView.AutoSizeColumnsMode set before, I use DataGridViewColumn.GetPreferredWidth() instead of changing DataGridViewColumn.AutoSizeMode and set the width value immediately, then change DataGridView.AutoSizeColumnsMode once:

    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;
    }
    
  • Be sure to set

            dataGridView.AllowUserToResizeColumns = true;
    
  • I don't know how come this only works after the form is shown.


I had to do this in VB and prefer to split it out to a method that I placed in a Module. You can add the Fill column as another ByRef parameter if desired.

''' <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

You could do something like this:

   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;

All columns will adapt to the content except the last one will fill the grid.

참고URL : https://stackoverflow.com/questions/1025670/how-do-you-automatically-resize-columns-in-a-datagridview-control-and-allow-the

반응형