Home > Back-end >  How to bind Array data to DataGrid and realize data update?
How to bind Array data to DataGrid and realize data update?

Time:12-28

I want to bind the Array to a 4-column DataGrid and update the data. Is this possible?

If it can't be achieved, how do I need to modify it?

For automatic updates, it seems that we can bind to some collection of objects with editable values is to define a class for the item. But i don't know how to do it.

 public partial class MainWindow : Window
  {
    int X=18;   
    public MainWindow()
    {
      InitializeComponent();
      int[] arr = new int[] { 61, 61, 61, 61, 61, 20, 30, 40, 50, 100, 200, 300, 400, 500, 0, 0, 0, 0, 0, 18, 23, 65, 41, 22, 91, 64, 33, 18, 44, 63, 91, 26, 32, 61, 83, 91, 26, 32, 91, 91, 91, 91 };
      DataGrid dataGrid = new DataGrid();
      dataGrid.AutoGenerateColumns = false;
      dataGrid.ItemsSource = arr.ToList();
      for (int i = 1; i < 5; i  )
      {
        DataGridTemplateColumn column = new DataGridTemplateColumn();
        column.Header = "Value" i;
        DataTemplate cellTemplate = new DataTemplate();
        FrameworkElementFactory textBlock = new FrameworkElementFactory(typeof(TextBlock));
        textBlock.SetBinding(TextBlock.TextProperty, new Binding("."));
        cellTemplate.VisualTree = textBlock;
        column.CellTemplate = cellTemplate;

        DataTemplate cellEditingTemplate = new DataTemplate();
        FrameworkElementFactory textBox = new FrameworkElementFactory(typeof(TextBox));
        textBox.SetBinding(TextBox.TextProperty, new Binding("."));
        cellEditingTemplate.VisualTree = textBox;
        column.CellEditingTemplate = cellEditingTemplate;

        dataGrid.Columns.Add(column);
      }
      canvas.Children.Add(dataGrid);
      Canvas.SetLeft(dataGrid, X);
    }
  }

The result:

enter image description here

I want a result like this:

61, 61, 61, 61, 61,

20, 30, 40, 50, 100,

200, 300, 400, 500, 0,

0, 0, 0, 0, 18,

CodePudding user response:

You can do it using arrays only. Note, that ItemsControl.ItemsSource is of type IEnumerable: you can assign the array directly to this property.
The ToList() call is redundant here.
Also use a DataGridTextColumn instead of the DataGridTemplateColumn to eliminate the modification of the cell templates, only to add a TextBlock.

DataGrid treats each item of its IEnumerable source collection as a row. This is why your table looks that way: each number is written into a new row. This is repeated for each column.

This means, you must change your data structure to adapt to the each-item-to-a-row rule. Because you have five columns, you have to structure your array to provide elements of 5-tuples (quintuple) - each quintuple element to a row.
You can achieve this by using a jagged array i.e. array of arrays.

Then when configuring the DataGrid.Columns, you have to use the binding indexer in order to extract the column's value from the array (row data).

"For automatic updates [...]"

You must know that there is no "automatic update" when using an array. If you want to modify the array while the application is running (dynamic data) you must use an ObservableCollection<int[]> instead of the int[][] jagged array.

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    this.Loaded  = onl oaded;
  }

  private void onl oaded(object sender, RoutedEventArgs e)
  {
    int[][] numbers = 
    { 
      new[] { 61, 61, 61, 61, 61 }, 
      new[] { 20, 30, 40, 50, 100 },
      new[] { 200, 300, 400, 500, 0 } 
    };
        
    this.NumbersDataGrid.ItemsSource = numbers;
 }
}

MainWindow.xaml

<Window>
    <DataGrid x:Name="NumbersDataGrid"
              AutoGenerateColumns="False">
    <DataGrid.Columns>
      <DataGridTextColumn Header="Value1"
                          Binding="{Binding [0]}" />
      <DataGridTextColumn Header="Value2"
                          Binding="{Binding [1]}" />
      <DataGridTextColumn Header="Value3"
                          Binding="{Binding [2]}" />
      <DataGridTextColumn Header="Value4"
                          Binding="{Binding [3]}" />
      <DataGridTextColumn Header="Value4"
                          Binding="{Binding [4]}" />
    </DataGrid.Columns>
  </DataGrid>
</Window>
  • Related