0
votes

I'm upgrading a WPF app to UWP, and I'm stuck with upgrading the DataGrid control. I'm trying to upgrade System.Windows.Controls.DataGrid (the old WPF control) -> Microsoft.Toolkit.Uwp.UI.Controls.DataGrid (the new MS recommended community control)

The old version works fine. It is populating the grid from a .NET DataTable. XAML:

<DataGrid SelectionMode="Single" SelectionChanged="dataGridSongs_SelectionChanged" BorderThickness="1" BorderBrush="LightGray" Margin="0 0" IsReadOnly="True" GridLinesVisibility="None" Name="dataGridSongs" ItemsSource="{Binding}">
</DataGrid>

Code behind:

public MainWindow()
{
    initializing = true;
    InitializeComponent();
    DataTable dt = dbHelper.GetAllSongs();
    dataGridSongs.DataContext = dt.DefaultView;
    dataGridSongs.HeadersVisibility = DataGridHeadersVisibility.None;
    initializing = false;
}

The new UWP DataGrid gives me an error: "BindingExpression path error: 'Item' property not found on 'System.Data.DataRowView'" And the grid is populated with some strange data: Wrong data

The new UWP app XAML:

<controls:DataGrid x:Name="dataGridSongs" ItemsSource="{Binding}">
</controls:DataGrid>

Code behind:

public MainPage()
{
    initializing = true;
    this.InitializeComponent();
    DataTable dt = dbHelper.GetAllSongs();
    dataGridSongs.DataContext = dt.DefaultView;
    //dataGridSongs.ItemsSource = dt.DefaultView;
}

I assume I'm populating the grid with the wrong objects, however, I couldn't find any example for this simple scenario.

2

2 Answers

0
votes

The UWP Community Toolkit DataGrid control doesn't support auto-generating columns for a DataView of a DataTable.

You may create the columns yourself though:

dataGridSongs.Columns.Clear();
dataGridSongs.AutoGenerateColumns = false;
for (int i = 0; i < dt.Columns.Count; i++)
{
    dataGridSongs.Columns.Add(new DataGridTextColumn()
    {
        Header = dt.Columns[i].ColumnName,
        Binding = new Binding { Path = new PropertyPath("[" + i.ToString() + "]") }
    });
}

var sourceCollection = new ObservableCollection<object>();
foreach (DataRow row in dt.Rows)
    sourceCollection.Add(row.ItemArray);

dataGridSongs.ItemsSource = sourceCollection;
0
votes

You could refer to the following sample which shows how to bind a DataGrid to a data source:

public class Customer
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public String Address { get; set; }
    public Boolean IsNew { get; set; }

    public Customer(String firstName, String lastName,
        String address, Boolean isNew)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Address = address;
        this.IsNew = isNew;
    }
}
public class ViewModel
{
    private List<Customer> m_customers;
    public List<Customer> Customers { get { return m_customers; }
    }
    public ViewModel()
    {
        m_customers = new List<Customer>(new Customer[4] {
        new Customer("A.", "Zero",
            "12 North Third Street, Apartment 45",
            false),
        new Customer("B.", "One",
            "34 West Fifth Street, Apartment 67",
            false),
        new Customer("C.", "Two",
            "56 East Seventh Street, Apartment 89",
            true),
        new Customer("D.", "Three",
            "78 South Ninth Street, Apartment 10",
            true)
    });
    }
}

MainPage class

public sealed partial class MainPage : Page
{
    public ViewModel MyViewModel;
    public MainPage()
    {
        this.InitializeComponent();
        MyViewModel = new ViewModel();
    }
}

MainPage.xaml

    <controls:DataGrid x:Name="dataGrid"  AutoGenerateColumns="True"
                       ItemsSource="{x:Bind MyViewModel.Customers}">
    </controls:DataGrid>

You could refer to the documetn for more information about data binding and customizing columns in DataGrid.