Search code examples
.netxamlmvvmwpfdatagrid

.Net 4 WPF DataGrid's ItemsSource - works programmatically, but not declaratively


I am writing a WPF program using C# and targeting .Net 4.0. I am trying to follow the MVVM pattern, where my view (code-behind) has minimal-to-no code.

I have a List<MyRecord> that I want to display in the GUI using a DataGrid. In my XAML, I have the following:

<DataGrid x:Name="RecordGrid" ...>
   <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding RecId}" Header="Record ID"/>
      <DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
   </DataGrid.Columns>
</DataGrid>

All that's left is to bind this grid to a data collection.

When I bind it in the code-behind file, it works fine:

RecordGrid.ItemsSource = MyRecordList;

However, I would prefer to bind it declaratively in XAML. So I tried this:

<DataGrid x:Name="RecordGrid" ItemsSource="{Binding MyRecordList}" ...>

but it silently doesn't work. There is no XAML binding error message when the datagrid loads. I set a breakpoint on MyRecordList's get method, and it's never invoked as long as ItemsSource is defined declaratively.

How can I get my datagrid to pull from MyRecordList via XAML?


Solution

  • You need to set the DataContext if you want the binding to work... The MVVM pattern has a View and a ViewModel. The View is your UI - e.g. the Window (Let's call it MainWindow) and your ViewModel is where you have the RecordGrid property and all theother commands/properties (let's call the class MainWindowViewModel)

    You need to connect them both, This is done by specifying in your View, who the DataContext is (in our case the MainWindowViewModel class).

    So you'll want to do something like this in your View's constructor:

        public MainWindow()
        {
            this.DataContext = new MainWindowViewModel();
            InitializeComponent();