source

프로그래밍 방식으로 WPF 데이터 그리드에 열 및 행 추가

myloves 2023. 4. 19. 00:42

프로그래밍 방식으로 WPF 데이터 그리드에 열 및 행 추가

WPF의 DataGrid에 열과 행을 프로그래밍 방식으로 추가하는 방법을 알고 싶습니다.Windows 폼에서 실행하던 방식입니다. 테이블 열과 행을 만들고 DataGrid에 바인딩합니다.

사용자가 셀의 데이터를 편집할 수 있도록 DataGrid에 그려야 하는 행과 열의 수가 있습니다.

행을 프로그래밍 방식으로 추가하려면:

DataGrid.Items.Add(new DataItem());

열을 프로그래밍 방식으로 추가하려면:

DataGridTextColumn textColumn = new DataGridTextColumn(); 
textColumn.Header = "First Name"; 
textColumn.Binding = new Binding("FirstName"); 
dataGrid.Columns.Add(textColumn); 

자세한 내용은 WPF DataGrid 토론 게시판의 이 게시물을 참조하십시오.

실행해 보세요.100% 동작합니다.프로그램적으로 열과 행을 추가합니다.먼저 항목 클래스를 만들어야 합니다.

public class Item
{
    public int Num { get; set; }
    public string Start { get; set; }
    public string Finich { get; set; }
}

private void generate_columns()
{
    DataGridTextColumn c1 = new DataGridTextColumn();
    c1.Header = "Num";
    c1.Binding = new Binding("Num");
    c1.Width = 110;
    dataGrid1.Columns.Add(c1);
    DataGridTextColumn c2 = new DataGridTextColumn();
    c2.Header = "Start";
    c2.Width = 110;
    c2.Binding = new Binding("Start");
    dataGrid1.Columns.Add(c2);
    DataGridTextColumn c3 = new DataGridTextColumn();
    c3.Header = "Finich";
    c3.Width = 110;
    c3.Binding = new Binding("Finich");
    dataGrid1.Columns.Add(c3);

    dataGrid1.Items.Add(new Item() { Num = 1, Start = "2012, 8, 15", Finich = "2012, 9, 15" });
    dataGrid1.Items.Add(new Item() { Num = 2, Start = "2012, 12, 15", Finich = "2013, 2, 1" });
    dataGrid1.Items.Add(new Item() { Num = 3, Start = "2012, 8, 1", Finich = "2012, 11, 15" });
}

저도 같은 문제가 있었어요.WPF에 새 행 추가DataGrid트릭이 필요합니다. DataGrid항목 개체의 속성 필드에 종속됩니다. ExpandoObject그럼 새로운 속성을 동적으로 추가할 수 있습니다.다음 코드에서는 그 방법을 설명합니다.

// using System.Dynamic;

DataGrid dataGrid;

string[] labels = new string[] { "Column 0", "Column 1", "Column 2" };

foreach (string label in labels)
{
    DataGridTextColumn column = new DataGridTextColumn();
    column.Header = label;
    column.Binding = new Binding(label.Replace(' ', '_'));

    dataGrid.Columns.Add(column);
}

int[] values = new int[] { 0, 1, 2 };

dynamic row = new ExpandoObject();

for (int i = 0; i < labels.Length; i++)
    ((IDictionary<String, Object>)row)[labels[i].Replace(' ', '_')] = values[i];

dataGrid.Items.Add(row);

//편집:

이 방법은 컴포넌트를 사용하는 방법이 아닙니다.단, 프로그래밍 방식으로 생성된 데이터(예: 일련의 피쳐와 뉴럴 네트워크 출력)만 있으면 컴포넌트가 많이 간소화됩니다.

런타임에 열을 추가하고 에 바인딩하는 솔루션을 찾았습니다.DataTable.

안타깝게도 47개의 열이 이렇게 정의되어 있기 때문에 데이터에 빠르게 바인딩되지 않습니다.좋은 의견이라도 있나?

xaml

<DataGrid
  Name="dataGrid"
  AutoGenerateColumns="False"
  ItemsSource="{Binding}">
</DataGrid>

xaml.cs 를 참조해 주세요.창문들.데이터

if (table != null) // table is a DataTable
{
  foreach (DataColumn col in table.Columns)
  {
    dataGrid.Columns.Add(
      new DataGridTextColumn
      {
        Header = col.ColumnName,
        Binding = new Binding(string.Format("[{0}]", col.ColumnName))
      });
  }

  dataGrid.DataContext = table;
}

edit: 죄송합니다.아래에 기재되어 있는 코드가 없습니다.그것은 복잡하지만 깔끔한 해결책이었다.


동적 Observable Collection 및 Dynamic Object와 함께 PropertyDescriptor 및 lamda 위임자를 사용하여 강하게 입력된 열 정의로 그리드를 채우는 방법을 설명하는 샘플 프로젝트를 게시했습니다.

열은 런타임에 동적으로 추가/제거할 수 있습니다.데이터가 알려진 유형의 개체가 아닌 경우 원하는 수의 열로 액세스할 수 있는 데이터 구조를 만들고 각 "열"에 대해 PropertyDescriptor를 지정할 수 있습니다.

예를 들어 다음과 같습니다.

IList<string> ColumnNames { get; set; }
//dict.key is column name, dict.value is value
Dictionary<string, string> Rows { get; set; }

다음과 같이 열을 정의할 수 있습니다.

var descriptors= new List<PropertyDescriptor>();
//retrieve column name from preprepared list or retrieve from one of the items in dictionary
foreach(var columnName in ColumnNames)
    descriptors.Add(new DynamicPropertyDescriptor<Dictionary, string>(ColumnName, x => x[columnName]))
MyItemsCollection = new DynamicDataGridSource(Rows, descriptors) 

또는 실제 물체의 경우 더 좋기도 합니다.

public class User 
{
    public string FirstName { get; set; }
    public string LastName{ get; set; }
    ...
}

데이터 모델과 관련된 강력한 유형의 열을 지정할 수 있습니다.

var propertyDescriptors = new List<PropertyDescriptor>
{
    new DynamicPropertyDescriptor<User, string>("First name", x => x.FirstName ),
    new DynamicPropertyDescriptor<User, string>("Last name", x => x.LastName ),
    ...
}

var users = retrieve some users

Users = new DynamicDataGridSource<User>(users, propertyDescriptors, PropertyChangedListeningMode.Handler);

그런 다음 사용자 컬렉션에 바인딩하면 열을 지정할 때 자동으로 생성됩니다.속성 설명자에 전달되는 문자열은 열 헤더의 이름입니다.실행 시 '사용자'에 PropertyDescriptor를 더 추가하여 그리드에 다른 열을 추가할 수 있습니다.

존 마이체크
, 이것이MVVM는 잘 .) ( 등) ('MVVM'에 준거하고 있는지 는 잘 .)

옵션 1: John B가 말한 대로.단, 약하게 입력된 DataTable 대신 자체 정의된 컬렉션을 사용해야 한다고 생각합니다(악의가 있는 것은 아니지만 각 열이 무엇을 나타내는지 코드에서는 알 수 없습니다).

xaml.cs

DataContext = myCollection;

//myCollection is a `ICollection<YourType>` preferably
`ObservableCollection<YourType>

 - option 2) Declare the name of the Datagrid in xaml

        <WpfToolkit:DataGrid Name=dataGrid}>

xaml.cs 에서 참조해 주세요.

CollectionView myCollectionView = 
      (CollectionView)CollectionViewSource.GetDefaultView(yourCollection);
dataGrid.ItemsSource = myCollectionView;

FirstName 속성이 정의된 유형인 경우 John Myczek이 지적한 대로 수행할 수 있습니다.

DataGridTextColumn textColumn = new DataGridTextColumn(); 
dataColumn.Header = "First Name"; 
dataColumn.Binding = new Binding("FirstName"); 
dataGrid.Columns.Add(textColumn); 

속성을 모르면 dataGrid에 표시할 필요가 있는 것은 분명하지만, 이 경우 해결해야 할 문제가 더 많아집니다.이러한 문제는 이 범위 밖이라고 생각합니다.

이미 데이터 바인딩이 있는 경우 John Myczek 답변이 완료되었습니다.그렇지 않은 경우 데이터 소스를 지정하려는 경우 최소 두 가지 옵션이 있습니다.(단, MVVM과 같은 대부분의 가이드라인에 부합하는지는 잘 모르겠습니다.)

그런 다음 사용자 컬렉션에 바인딩하면 열을 지정할 때 자동으로 생성됩니다.속성 설명자에 전달되는 문자열은 열 헤더의 이름입니다.실행 시 '사용자'에 PropertyDescriptor를 더 추가하여 그리드에 다른 열을 추가할 수 있습니다.

CodeBehind의 DataGridTextColumn에 DataTable을 바인드하려면 xaml

<DataGrid
  Name="TrkDataGrid"
  AutoGenerateColumns="False"
  ItemsSource="{Binding}">
</DataGrid>

xaml.cs

  foreach (DataColumn col in dt.Columns)
  {
    TrkDataGrid.Columns.Add(
      new DataGridTextColumn
      {
        Header = col.ColumnName,
        Binding = new Binding(string.Format("[{0}]", col.ColumnName))
      });
  }

  TrkDataGrid.ItemsSource= dt.DefaultView;

언급URL : https://stackoverflow.com/questions/704724/programmatically-add-column-rows-to-wpf-datagrid