Why isn't my WPF Datagrid showing data?
Asked Answered
F

6

9

This walkthrough says you can create a WPF datagrid in one line but doesn't give a full example.

So I created an example using a generic list and connected it to the WPF datagrid, but it doesn't show any data.

What do I need to change on the code below to get it to show data in the datagrid?

ANSWER:

This code works now:

XAML:

<Window x:Class="TestDatagrid345.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:local="clr-namespace:TestDatagrid345"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <StackPanel>
        <toolkit:DataGrid ItemsSource="{Binding}"/>
    </StackPanel>
</Window>

Code Behind:

using System.Collections.Generic;
using System.Windows;

namespace TestDatagrid345
{
    public partial class Window1 : Window
    {
        private List<Customer> _customers = new List<Customer>();
        public List<Customer> Customers { get { return _customers; }}

        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = Customers;

            Customers.Add(new Customer { FirstName = "Tom", LastName = "Jones" });
            Customers.Add(new Customer { FirstName = "Joe", LastName = "Thompson" });
            Customers.Add(new Customer { FirstName = "Jill", LastName = "Smith" });
        }
    }
}
Fortunetelling answered 23/3, 2009 at 10:51 Comment(1)
Just also move the DataContext = Customers below where you actually call Customers.Add! You are using List<Customer> which has now change notification! If you really need change notification, use the ObservableCollection<Customer>Cecrops
C
1

Now remove the Path=Customers from your binding, and it should work :)

Clairvoyant answered 23/3, 2009 at 11:43 Comment(2)
no that still doesn't work, I reposted the current code that doesn't work above.Fortunetelling
You still need the Binding... like so: ItemsSource={Binding}Clairvoyant
M
8

Typically in WPF, you would leverage an ObservableCollection<>

Because then you can just .Add() / .Remove() elements to/from the source collection, and any controls bound (Data Binding) automatically get updated (Automatic Property Change Notification). Those are 2 important concepts in WPF.

Main Window View Model

using System.Collections.Generic;

namespace TestDatagrid345.ViewModels
{
  class Window1ViewModel
  {
    private ObservableCollection<Customer> _customers = new ObservableCollection<Customer>();
    public ObservableCollection<Customer> Customers
    {
      Get { return _customers; }
    }
  }
}

Main Window

using System.Collections.Generic;
using System.Windows;

namespace TestDatagrid345
{
  public partial class Window1 : Window
  {
    Window1ViewModel _viewModel;

    public Window1()
    {
      InitializeComponent();
      _viewModel = (Window1ViewModel)this.DataContext; // @#$% (see XAML)
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      // but this stuff could instead be done on a 'Submit' button click on form:
      _viewModel.Customers.Add(new Customer { FirstName = "Tom", LastName = "Jones" });
      _viewModel.Customers.Add(new Customer { FirstName = "Joe", LastName = "Thompson" });
      _viewModel.Customers.Add(new Customer { FirstName = "Jill", LastName = "Smith" });
    }
  }
}

Main Window XAML

<Window
  x:Class="TestDatagrid345.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:vm="clr-namespace:TestDatagrid345.ViewModels"
  Title="Window1"
  Height="350"
  Width="525"
  WindowState="Maximized">
  <Window.DataContext>
    <vm:Window1ViewModel /> <!-- this needs to be here for @#$% -->
  </Window.DataContext>
  <Grid>
   <DataGrid
      AutoGenerateColumns="True"
      ItemsSource="{Binding Path=Customers}"
      AlternatingRowBackground="LightBlue"
      AlternationCount="2" />
  </Grid>
</Window>
Moreen answered 10/1, 2011 at 23:33 Comment(0)
C
3

You need to add

DataContext = Customers;

In your Window_Loaded()

Cecrops answered 23/3, 2009 at 10:58 Comment(1)
I added DataContext = Customers to Window_Loaded() but the datagrid still displays no data. I'm quite sure I've done this binding before with a generic list, and I thought the Datagrid just read the fields of the generic object out. I'm using the March 2009 version of the Toolkit.Fortunetelling
E
2

try it: populate you _customers list and asign property ItemsSource

        dataGrid1.ItemsSource = _customers;
Exhilarant answered 21/3, 2010 at 21:6 Comment(0)
G
2

I was trying to figure out why the identical code as given by JohnB's answer did not work for me, and the problem was that the model object (Customer) did not have properties, but fields. Converting them to properties fixed my problem.

Genesis answered 18/2, 2019 at 11:24 Comment(0)
C
1

Now remove the Path=Customers from your binding, and it should work :)

Clairvoyant answered 23/3, 2009 at 11:43 Comment(2)
no that still doesn't work, I reposted the current code that doesn't work above.Fortunetelling
You still need the Binding... like so: ItemsSource={Binding}Clairvoyant
I
0

Found this behavior. selecting same field from 2 tables with table prefix A. , B. need to name fields with AS.. No values in datagrid: SELECT A.F_Nummer, B.F_Nummer Like this get values SELECT A.F_Nummer as A_F_Nummer, B.F_Nummer as B_F_Nummer

Identity answered 2/9, 2024 at 6:41 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Effortful

© 2022 - 2025 — McMap. All rights reserved.