How to fill DataGrid with DataTable content in UWP c#
Asked Answered
F

2

8

I'm creating a UWP app and trying to fill my DataGrid with a DataTable that contains data from my database, but with no success. I have already searched for solutions but just can't get rid of the error.

XAML code:

<StackPanel>
    <Button Content="Fill DataGrid" Click="Button_Click"/>
    <controls:DataGrid x:Name="dataGrid"
                       Margin="30"
                       AutoGenerateColumns="True">
    </controls:DataGrid>
</StackPanel>

C# code:

    private static DataTable GetDataTable()
    {
        DataTable dt = new DataTable();

        dt.Columns.Add("ID", typeof(int));
        dt.Columns.Add("FirstName", typeof(string));
        dt.Columns.Add("LastName", typeof(string));
        dt.Columns.Add("Address", typeof(string));
        dt.Columns.Add("City", typeof(string));

        for (int i = 0; i < 10; i++)
            dt.Rows.Add(i, "text", "text", "text", "text");

        return dt;
    }

    private  void Button_Click(object sender, RoutedEventArgs e)
    {
        DataTable dt = GetDataTable();
        dataGrid.ItemsSource = dt.DefaultView; 
    }

This is what i get with the code above

and this error 20 times (the table has 10 entries)

Error: BindingExpression path error: 'Item' property not found on 'System.Data.DataRowView'. BindingExpression: Path='Item' DataItem='System.Data.DataRowView'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')

When i swap ItemSource with DataContext:

 dataGrid.DataContext = dt.DefaultView; 

I don't get any error but I also don't change the dataGrid in any way.

I have tried to do the same in windows forms with DataGridView and I have succeeded:

private void button_Click(object sender, EventArgs e)
{
    DataTable dt = GetDataTableFromDatabase();
    dataGridView1.DataSource = dt;
}

I get this so its not a problem with the database or the DataTable.

enter image description here I have managed to achieve a workaround by creating a List with the entities from the DataTable and adding them as the source to the dataGrid, but the problem is that I have a lot of different DataGrids and it would be a lot easier if i could somehow solve the problem in a way similar to the example in windows forms with the dataGridView.

Any help is appreciated.

Fiveandten answered 11/12, 2018 at 18:24 Comment(2)
I edited your case, But ,it is hard to reproduce the issue with the above code. could you share a mini sample?Mcreynolds
@NicoZhu-MSFT I edited the code a bit, this sample shows the same behaviour.Fiveandten
F
11

I figured it out thanks to this site.

    public static void FillDataGrid(DataTable table, DataGrid grid)
    {
        grid.Columns.Clear();
        grid.AutoGenerateColumns = false;
        for (int i = 0; i < table.Columns.Count; i++)
        {
            grid.Columns.Add(new DataGridTextColumn()
            {
                Header = table.Columns[i].ColumnName,
                Binding = new Binding { Path = new PropertyPath("[" + i.ToString() + "]") }
            });
        }

        var collection = new ObservableCollection<object>();
        foreach (DataRow row in table.Rows)
        {
            collection.Add(row.ItemArray);
        }

        grid.ItemsSource = collection;
    }

Maybe not the most elegant way to solve this but it works, and it does exactly what i want.

And you have to set the dataGrid property "AutoGenerateColums" to "False". That was causing me a lot of problems.

Fiveandten answered 13/12, 2018 at 17:19 Comment(1)
Where do you declare the ObservableCollection on the xaml page? I can't use the column item templates because it keeps saying there is no ObservableCollection. Did some searching on that and it just hasn't clicked with me yet on how to do that when binding from the codebehind. Thanks.Gabbro
G
0

I don't know that this is a better answer, but I just about had this working when I found this question. I'm used to Asp.Net, so this is what I came up with.

On xaml page (or using) xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"

nModel.Data.ListData = a class file.

 public class ListData
{
    public string HashId { get; set; }
    public int SortOrder { get; set; }
    public string StrSortOrder { get; set; }
    public string DataPoint { get; set; }
    public string Rfid { get; set; }
    public string Description { get; set; }
    public string Attch { get; set; }
}

And in the page codebehind:

   DataTable dt = new DataTable();
        dt = nModel.DataDAL.ListData.ListDataDataTable("30039");

        List<nModel.Data.ListData> dataList = new List<nModel.Data.ListData>();
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            nModel.Data.ListData ListData = new nModel.Data.ListData();
            ListData.StrSortOrder = dt.Rows[i]["SortOrder"].ToString();
            ListData.DataPoint = dt.Rows[i]["DataPoint"].ToString();
            ListData.Rfid = dt.Rows[i]["Rfid"].ToString();
            dataList.Add(ListData);
        }
       
        dataGrid.ItemsSource = dataList;

And the grid

<controls:DataGrid x:Name="dataGrid"
                       AutoGenerateColumns="False">
        <controls:DataGrid.Columns>
            <controls:DataGridTextColumn Header="Piece#"
                                         Binding="{Binding StrSortOrder}"/>
            <controls:DataGridTextColumn Header="SerialNo"
                                         Binding="{Binding DataPoint}"/>
            <controls:DataGridTextColumn Header="Rfid"
                                         Binding="{Binding Rfid}"/>
            
        </controls:DataGrid.Columns>
        </controls:DataGrid>

It's pretty evident after spending a few days learning uwp, why nobody uses DataTables.

The GridView and ListView controls are not anything like the Asp.Net versions. It's not even clear that the DataGrid control is even a thing. I was somewhat frustrated by the time I came back to this question and dug a little deeper.

Thanks for asking it...

Gabbro answered 26/1, 2021 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.