Windows Forms DataGridView 컨트롤의 크기 조정에 대한 모범 사례

DataGridView 컨트롤은 최대 확장성을 제공하도록 설계되었습니다. 많은 양의 데이터를 표시해야 하는 경우 이 항목에 설명된 지침을 따라 많은 양의 메모리를 사용하거나 UI(사용자 인터페이스)의 응답성을 저하하지 않도록 해야 합니다. 이 항목에서는 다음 이슈에 대해 설명합니다.

  • 셀 스타일을 효율적으로 사용

  • 바로 가기 메뉴를 효율적으로 사용

  • 자동 크기 조정을 효율적으로 사용

  • 선택한 셀, 행 및 열 컬렉션을 효율적으로 사용

  • 공유 행 사용

  • 행이 공유되지 않도록 방지

특별한 성능 요구 사항이 있는 경우 가상 모드를 구현하고 고유한 데이터 관리 작업을 제공할 수 있습니다. 자세한 내용은 Windows Forms DataGridView 컨트롤의 데이터 표시 모드를 참조세요.

셀 스타일을 효율적으로 사용

각 셀, 행 및 열에는 고유한 스타일 정보가 있을 수 있습니다. 스타일 정보는 DataGridViewCellStyle 개체에 저장됩니다. 많은 개별 DataGridView 요소에 대한 셀 스타일 개체를 만드는 것은 특히 많은 양의 데이터로 작업할 때는 비효율적일 수 있습니다. 성능에 영향을 주지 않도록 하려면 다음 지침을 사용합니다.

바로 가기 메뉴를 효율적으로 사용

각 셀, 행 및 열에는 고유한 바로 가기 메뉴가 있을 수 있습니다. DataGridView 컨트롤의 바로 가기 메뉴는 ContextMenuStrip 컨트롤로 표시됩니다. 셀 스타일 개체와 마찬가지로 많은 개별 DataGridView 요소에 대한 바로 가기 메뉴를 만들면 성능에 부정적인 영향을 줍니다. 이 페널티를 방지하려면 다음 지침을 사용합니다.

  • 개별 셀 및 행에 대한 바로 가기 메뉴를 만들지 마세요. 여기에는 새 행이 컨트롤에 추가되면 바로 가기 메뉴와 함께 복제되는 행 템플릿이 포함됩니다. 확장성을 극대화하려면 컨트롤의 ContextMenuStrip 속성만 사용하여 전체 컨트롤에 대한 단일 바로 가기 메뉴를 지정합니다.

  • 여러 행 또는 셀에 대해 여러 바로 가기 메뉴가 필요한 경우 CellContextMenuStripNeeded 또는 RowContextMenuStripNeeded 이벤트를 처리합니다. 이러한 이벤트를 사용하면 바로 가기 메뉴 개체를 직접 관리하여, 성능을 조정할 수 있습니다.

자동 크기 조정을 효율적으로 사용

셀 내용이 변경되면 행, 열 및 머리글의 크기를 자동으로 조정하여 셀의 전체 내용이 클리핑 없이 표시되도록 할 수 있습니다. 크기 조정 모드를 변경하면 행, 열 및 머리글의 크기를 조정할 수도 있습니다. 올바른 크기를 확인하려면 DataGridView 컨트롤이 수용해야 하는 각 셀의 값을 검사해야 합니다. 큰 데이터 세트로 작업할 때 이 분석은 자동 크기 조정이 발생할 때 컨트롤의 성능에 부정적인 영향을 미칠 수 있습니다. 성능 저하를 방지하려면 다음 지침을 사용합니다.

자세한 내용은 Windows Forms DataGridView 컨트롤의 크기 조정 옵션을 참조하세요.

선택한 셀, 행 및 열 컬렉션을 효율적으로 사용

SelectedCells 컬렉션이 대규모 선택에서는 효율적으로 수행되지 않습니다. 일반적인 DataGridView 컨트롤의 셀보다 행 수가 적고 행보다 열 수가 적기 때문에, SelectedRowsSelectedColumns 컬렉션은 정도가 낮더라도, 비효율적일 수 있습니다. 이러한 컬렉션을 사용할 때 성능 저하를 방지하려면 다음 지침을 사용합니다.

공유 행 사용

효율적인 메모리 사용은 공유 행을 통해 DataGridView 컨트롤에서 달성됩니다. 행은 DataGridViewRow 클래스의 인스턴스를 공유하여 모양 및 동작에 대한 정보를 최대한 많이 공유합니다.

행 인스턴스를 공유하면 메모리가 절약되지만 행은 쉽게 공유되지 않게 될 수 있습니다. 예를 들어, 사용자가 셀과 직접 상호 작용할 때마다 해당 행은 공유되지 않게 됩니다. 이 문제를 피할 수 없으므로 이 항목의 지침은 매우 많은 양의 데이터를 사용하는 경우에만 유용하며 프로그램이 실행될 때마다 사용자가 데이터의 상대적으로 작은 부분과 상호 작용하는 경우에만 유용합니다.

셀에 값이 포함된 경우 행은 바인딩되지 않은 DataGridView 컨트롤에서 공유할 수 없습니다. DataGridView 컨트롤이 외부 데이터 원본에 바인딩되거나 가상 모드를 구현하고 사용자 고유의 데이터 원본을 제공하는 경우, 셀 값은 셀 개체가 아닌 컨트롤 외부에 저장되므로 행을 공유할 수 있습니다.

행 개체는 행의 상태와 셀이 포함된 열의 상태에서 모든 셀의 상태를 확인할 수 있는 경우에만 공유할 수 있습니다. 행과 열의 상태에서 더 이상 추론할 수 없도록 셀의 상태를 변경하면 행을 공유할 수 없습니다.

예를 들어, 다음 상황에서는 행을 공유할 수 없습니다.

바인딩 모드 또는 가상 모드에서는 CellToolTipTextNeededCellContextMenuStripNeeded 이벤트를 처리하여 개별 셀에 대한 도구 설명 및 바로 가기 메뉴를 제공할 수 있습니다.

DataGridView 컨트롤은 행이 DataGridViewRowCollection에 추가될 때마다 공유 행을 자동으로 사용하려고 시도합니다. 다음 지침을 사용하여 행이 공유되도록 합니다.

행이 공유되는지 여부를 확인하려면 DataGridViewRowCollection.SharedRow 메서드를 사용하여 행 개체를 검색한 다음, 개체의 Index 속성을 확인합니다. 공유 행의 Index 속성 값은 항상 -1입니다.

행이 공유되지 않도록 방지

공유 행은 코드 또는 사용자 작업의 결과로 공유되지 않게 될 수 있습니다. 성능에 영향을 주지 않도록 하려면 행이 공유되지 않도록 해야 합니다. 애플리케이션 개발 중, RowUnshared 이벤트를 처리하여 행이 공유되지 않는 시기를 결정할 수 있습니다. 이는 행 공유 문제를 디버깅할 때 유용합니다.

행이 공유되지 않도록 하려면 다음 지침을 사용합니다.

  • Rows 컬렉션을 인덱싱하거나 foreach 루프를 사용하여 반복하지 마세요. 일반적으로 행에 직접 액세스할 필요가 없습니다. 행에서 작동하는 DataGridView 메서드는 행 인스턴스가 아닌 행 인덱스 인수를 사용합니다. 뿐만 아니라, 행 관련 이벤트용 처리기는 행이 공유되지 않게 하지 않고 행을 조작하는 데 사용할 수 있는 행 속성이 있는 이벤트 인수 개체를 수신합니다.

  • 행 개체에 액세스해야 하는 경우 DataGridViewRowCollection.SharedRow 메서드를 사용하고 행의 실제 인덱스로 전달합니다. 그러나 이 메서드를 통해 검색된 공유 행 개체를 수정하면 이 개체를 공유하는 모든 행이 수정됩니다. 그러나 새 레코드의 행은 다른 행과 공유되지 않으므로, 다른 행을 수정할 때는 영향을 받지 않습니다. 또한 공유 행으로 표시되는 다른 행에는 다른 바로 가기 메뉴가 있을 수 있습니다. 공유 행 인스턴스에서 올바른 바로 가기 메뉴를 검색하려면 GetContextMenuStrip 메서드를 사용하고 행의 실제 인덱스로 전달합니다. 대신 공유 행의 ContextMenuStrip 속성에 액세스하는 경우 -1의 공유 행 인덱스가 사용되며 올바른 바로 가기 메뉴를 검색하지 않습니다.

  • DataGridViewRow.Cells 컬렉션을 인덱싱하지 마세요. 셀에 직접 액세스하면 부모 행이 공유되지 않게 되고 새 DataGridViewRow가 인스턴스화됩니다. 셀 관련 이벤트용 처리기는 행이 공유되지 않게 하지 않고 셀을 조작하는 데 사용할 수 있는 셀 속성이 있는 이벤트 인수 개체를 수신합니다. 또한 CurrentCellAddress 속성을 사용하여 셀에 직접 액세스하지 않고 현재 셀의 행 및 열 인덱스를 검색할 수 있습니다.

  • 셀 기반 선택 모드를 사용하지 마세요. 이러한 모드로 인해 행이 공유되지 않습니다. 대신, DataGridView.SelectionMode 속성을 DataGridViewSelectionMode.FullRowSelect 또는 DataGridViewSelectionMode.FullColumnSelect로 설정합니다.

  • DataGridViewRowCollection.CollectionChanged 또는 DataGridView.RowStateChanged 이벤트를 처리하지 마세요. 이러한 이벤트로 인해 행이 공유되지 않습니다. 또한 이러한 이벤트를 발생시키는 DataGridViewRowCollection.OnCollectionChanged 또는 DataGridView.OnRowStateChanged 메서드도 호출하지 마세요.

  • DataGridView.SelectionMode 속성 값이 FullColumnSelect, ColumnHeaderSelect, FullRowSelect 또는 RowHeaderSelect일 때 DataGridView.SelectedCells 컬렉션에 액세스하지 마세요. 이렇게 하면 선택한 모든 행이 공유되지 않게 됩니다.

  • DataGridView.AreAllCellsSelected 메서드를 호출하지 마세요. 이 메서드는 행이 공유되지 않게 할 수 있습니다.

  • DataGridView.SelectionMode 속성 값이 CellSelect일 때 DataGridView.SelectAll 메서드를 호출하지 마세요. 그럴 경우 모든 행이 공유되지 않게 됩니다.

  • 열의 해당 속성이 true로 설정된 경우 셀의 ReadOnly 또는 Selected 속성을 false로 설정하지 마세요. 그럴 경우 모든 행이 공유되지 않게 됩니다.

  • DataGridViewRowCollection.List 속성에 액세스하지 마세요. 그럴 경우 모든 행이 공유되지 않게 됩니다.

  • Sort 메서드의 Sort(IComparer) 오버로드를 호출하지 마세요. 사용자 지정 비교자를 사용하여 정렬하면 모든 행이 공유되지 않게 됩니다.

참고 항목