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>