Samed Bejtovic
Samed Bejtovic

Reputation: 301

How to fill DataGrid with DataTable content in UWP c#

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.

Upvotes: 8

Views: 5658

Answers (2)

user1544428
user1544428

Reputation: 150

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...

Upvotes: 0

Samed Bejtovic
Samed Bejtovic

Reputation: 301

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.

Upvotes: 11

Related Questions