AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
24.55k stars 2.12k forks source link

Improve DataGrid binding to System.Data.DataTable #2781

Open Ravatsaas opened 4 years ago

Ravatsaas commented 4 years ago

I'm playing around with Avalonia, and got stuck trying to bind a DataGrid control to a DataTable.

In WPF binding the DataGrid to the table's DefaultView property causes the table's data to display. The Avalonia DataGrid just shows the properties of the row object.

It would be a nice feature to have if it would know by default how to bind to a DataTable (or really the DataView attached to the table).

I suspect there could be a possible workaround, defining a DataTemplate, but I haven't figured it out yet. Any tips would be welcome.

Ravatsaas commented 4 years ago

For anyone struggling with the same problem, here's the workaround I came up with:

  1. Expose the DataTable's default view on the ViewModel:
        public DataView DataView
        {
            get => _dataTable.DefaultView;
        }
  2. Bind it up like this (XAML):
      <DataGrid Name="MyGrid" Items="{Binding DataView}">
      </DataGrid>
  3. In the codebehind (.xaml.cs file), add a handler for the Activated event

        public MainWindow()
        {
            Activated += MainWindow_Activated; // <-- This line
    
            InitializeComponent();
    #if DEBUG
            this.AttachDevTools();
    #endif
        }
  4. Implement the event handler like this:

        private void MainWindow_Activated(object sender, System.EventArgs e)
        {
            var grid = this.FindControl<DataGrid>("MyGrid");
            var vm = (MainWindowViewModel)DataContext;
    
            var cols = vm.DataView.Table.Columns;
    
            for (var i = 0; i < cols.Count; i++)
            {
                grid.Columns.Add(new DataGridTextColumn
                {
                    Header = cols[i].ColumnName,
                    Binding = new Binding($"Row.ItemArray[{i}]"),
                });
            }
        }
hematec commented 2 years ago

Hello,

are there any news on this topic? When i try above suggestion, i'm not able to change the DataTable data in the DataGrid.

FoggyFinder commented 2 years ago

When i try above suggestion, i'm not able to change the DataTable data in the DataGrid.

@hematec yes. I had the same issue and have to create new DataGrid each time

qq908382818 commented 3 months ago
  Binding = new Binding($"Row.ItemArray[{i}]"), it's ok.how change to axaml binding code.

<--DataGrid.Columns> <--DataGridTextColumn Binding="{Binding Row.ItemArray[0]"/> <--/DataGrid.Columns>

qq908382818 commented 3 months ago

DataGridTextColumn colTmp = new() { //Binding = new Binding($"Row.ItemArray[{i}]"), Binding = new Binding($"Row.ItemArray[\"{dt1.Columns[i].ColumnName}\"]"), //how to work }; What does this code mean? Is there any explanation corresponding to DataTable or List or list or other type ?