I have a ObservableCollection
of my Movie
class which has a string property name Name
, I want it to be displayed in a DataGrid
in WPF.
<Window x:Class="MovieList.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:MovieList"
mc:Ignorable="d"
Title="Movie List" Height="450" Width="800">
<Grid>
<DataGrid ItemsSource="{Binding movies}" AlternatingRowBackground="Gray" >
</DataGrid>
</Grid>
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.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MovieList
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ObservableCollection<Movie> movies;
public MainWindow()
{
movies = new ObservableCollection<Movie>();
foreach (string dir in Directory.GetDirectories(@"F:\")) {
movies.Add(new Movie(dir));
}
InitializeComponent();
}
}
public class Movie
{
public string Name { get; set; }
public Movie(string movieName)
{
Name = movieName;
}
}
}
You cannot bind to fields, make movies
a public
property and use pascal casing as per convention.
public ObservableCollection<Movie> Movies { get; }
You create your Movies
collection in code-behind, but bindings work on the DataContext
that is inherited from parent controls all the way up to your window, where it is unset. You can set it there:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Or you can use a relative source with ancestor type to refer to the window in the ItemsSource
binding.
<DataGrid ItemsSource="{Binding Movies, RelativeSource={RelativeSource AncestorType={x:Type local:MainWindowWindow}}}"
AlternatingRowBackground="Gray">
Since the DataGrid
auto-generates columns from properties of the bound type by default, you do not have to create columns yourself. However, if you want to, set AutoGenerateColumns
to false
.
<DataGrid ItemsSource="{Binding Movies}"
AlternatingRowBackground="Gray"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
</DataGrid.Columns>
</DataGrid>
If you miss that, you will have duplicate columns, the auto-generated ones and your own.