Posts Display list of customers using a Datagrid
Post
Cancel

Display list of customers using a Datagrid

MainWindow.xaml

  • Add a DataGrid to MainWindow.xaml
  • Set its ItemsSource property to a CollectionViewSource
  • Define a CollectionViewSource. Name it with a key and set the Source property to Binding Customers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<Window x:Class="DataGridDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <CollectionViewSource x:Key="CustomersCollectionViewSource" Source="{Binding Customers}" />
    </Window.Resources>
    <Grid>
        <DataGrid Name = "dataGrid" 
                  AlternatingRowBackground = "LightBlue"  
                  AlternationCount = "2" 
                  AutoGenerateColumns = "False"
                  ItemsSource="{Binding Source={StaticResource CustomersCollectionViewSource}}">
            <DataGrid.Columns>
                <DataGridTextColumn Header = "Last Name" Binding = "{Binding LastName}" />
                <DataGridTextColumn Header = "First Name" Binding = "{Binding FirstName}" />
                <DataGridCheckBoxColumn Header = "IsCompany?" Binding = "{Binding IsCompany}"/>
                <DataGridTextColumn Header = "Email" Binding = "{Binding Email}" />
            </DataGrid.Columns>

        </DataGrid>

    </Grid>
</Window>

In MainWindow.xaml.cs

  • Declare public MainWindowViewModel viewModel;
  • Set path to [directory]/customers.xml
  • Remember to set Build Action of customers.xml to Resource and Do Not Copy to output directory.
  • Instantiate the MainWindowViewModel by calling the constructor and passing the path
  • Assign the viewModel to the DataContext of MainWindow.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using DataGridDemo.ViewModel;

using System.Windows;


namespace DataGridDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindowViewModel viewModel;
        public MainWindow()
        {
            string path = "Data/customers.xml";
            viewModel = new MainWindowViewModel(path);
            this.DataContext = viewModel;

            InitializeComponent();
        }
    }
}

The Model: Customer.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataGridDemo.Model
{
    public class Customer
    {
        #region Creation
        public static Customer CreateCustomer(
            double totalSales,
            string firstName,
            string lastName,
            bool isCompany,
            string email)
        {
            return new Customer
            {
                TotalSales = totalSales,
                FirstName = firstName,
                LastName = lastName,
                IsCompany = isCompany,
                Email = email
            };
        }
        protected Customer()
        {
        }

        #endregion // Creation

        #region State Properties

        /// <summary>
        /// Gets/sets the e-mail address for the customer.
        /// </summary>
        public string? Email { get; set; }

        /// <summary>
        /// Gets/sets the customer's first name.  If this customer is a 
        /// company, this value stores the company's name.
        /// </summary>
        public string? FirstName { get; set; }

        /// <summary>
        /// Gets/sets whether the customer is a company or a person.
        /// The default value is false.
        /// </summary>
        public bool IsCompany { get; set; }

        /// <summary>
        /// Gets/sets the customer's last name.  If this customer is a 
        /// company, this value is not set.
        /// </summary>
        public string? LastName { get; set; }

        /// <summary>
        /// Returns the total amount of money spent by the customer.
        /// </summary>
        public double TotalSales { get; private set; }

        #endregion // State Properties
    }
}

The ViewModel: MainWindowViewModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using DataGridDemo.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml;
using System.Windows.Resources;
using System.Windows;

namespace DataGridDemo.ViewModel
{
    public class MainWindowViewModel
    {
        readonly List<Customer> _customers;
        public ObservableCollection<Customer>? Customers
        {
            get
            {
                return new ObservableCollection<Customer>(_customers);
            }
        }

        public MainWindowViewModel(string customerDataFile)
        {
            _customers = LoadCustomers(customerDataFile);

        }


        static List<Customer> LoadCustomers(string customerDataFile)
        {
            // In a real application, the data would come from an external source,
            // but for this demo let's keep things simple and use a resource file.
            using (Stream stream = GetResourceStream(customerDataFile))
            using (XmlReader xmlRdr = new XmlTextReader(stream))
                return
                    (from customerElem in XDocument.Load(xmlRdr).Element("customers").Elements("customer")
                     select Customer.CreateCustomer(
                        (double)customerElem.Attribute("totalSales"),
                        (string)customerElem.Attribute("firstName"),
                        (string)customerElem.Attribute("lastName"),
                        (bool)customerElem.Attribute("isCompany"),
                        (string)customerElem.Attribute("email")
                         )).ToList();
        }

        static Stream GetResourceStream(string resourceFile)
        {
            Uri uri = new Uri(resourceFile, UriKind.RelativeOrAbsolute);

            StreamResourceInfo info = Application.GetResourceStream(uri);
            if (info == null || info.Stream == null)
                throw new ApplicationException("Missing resource file: " + resourceFile);

            return info.Stream;
        }
    }
}

Here is a sample customers.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<customers>
  <customer lastName="Smith"      firstName="Josh"    isCompany="false" email="josh@contoso.com"    totalSales="32132.92" />
  <customer lastName="Bujak"      firstName="Greg"    isCompany="false" email="greg@contoso.com"    totalSales="9848.06"  />
  <customer lastName="Crafton"    firstName="Jim"     isCompany="false" email="crafton@contoso.com" totalSales="6132.34"  />
  <customer lastName="Nolan"      firstName="Jordan"  isCompany="false" email="jordan@contoso.com"  totalSales="12993.01" />
  <customer lastName="Hinkson"    firstName="Grant"   isCompany="false" email="hinkson@contoso.com" totalSales="4322.81"  />
  <customer lastName="Shifflett"  firstName="Karl"    isCompany="false" email="kdawg@contoso.com"   totalSales="8821.87"  />
  <customer lastName="Walker"     firstName="Wilfred" isCompany="false" email="will@contoso.com"    totalSales="3509.37"  />
  <customer lastName="McCort"     firstName="Denise"  isCompany="false" email="denise@contoso.com"  totalSales="2222.05"  />

  <customer lastName="" firstName="Alfreds Futterkiste" isCompany="true" email="maria@contoso.com"  totalSales="8832.16"   />
  <customer lastName="" firstName="Eastern Connection"  isCompany="true" email="ann@contoso.com"    totalSales="12831.73"  />
  <customer lastName="" firstName="Hanari Carnes"       isCompany="true" email="alex@contoso.com"   totalSales="473764.02" />
  <customer lastName="" firstName="Königlich Essen"     isCompany="true" email="philip@contoso.com" totalSales="28112.50"  />
</customers>
This post is licensed under CC BY 4.0 by the author.