Jamesits
Jamesits

Reputation: 642

WPF DataGrid not updating with binded BindingList

I have a BindingList binded to a DataGrid, but when I add item to that list, UI is not updating.

Here is a minimal version of code that can reproduce this problem:

MainWindow.xaml

<Window x:Class="WpfTestApp1.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:WpfTestApp1"
        mc:Ignorable="d"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource x:Key="SessionSource" Source="{Binding Sessions}" />
    </Window.Resources>
    <Grid>
        <DockPanel LastChildFill="True">
            <StackPanel DockPanel.Dock="Right">
                <Button x:Name="BtnTest" Click="BtnTest_OnClick" Content="Test"></Button>
            </StackPanel>
            <DataGrid x:Name="DG" DockPanel.Dock="Right" ItemsSource="{Binding Source={StaticResource SessionSource}}">
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="UserName" Width="Auto" Header="Title" Binding="{Binding Title}"/>
                    <DataGridTextColumn x:Name="UserAction" Width="Auto" Header="Host" Binding="{Binding Host}"/>
                </DataGrid.Columns>
            </DataGrid>
        </DockPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfTestApp1
{
    public class Session : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _title;
        public string Title { get => _title; set { _title = value; OnPropertyChanged(); } }
        private string _host;
        public string Host { get => _host; set { _host = value; OnPropertyChanged(); } }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public partial class MainWindow : Window
    {
        public BindingList<Session> Sessions { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            Sessions = new BindingList<Session>();
        }

        private void BtnTest_OnClick(object sender, RoutedEventArgs e)
        {
            Sessions.Add(new Session(){Title = "test1", Host="test2"});
        }
    }
}

Tried to implement INotifyPropertyChanged interface in MainWindow class, but seems not working too.

Upvotes: 2

Views: 978

Answers (1)

Clemens
Clemens

Reputation: 128013

Initialize the Sessions property before calling InitializeComponent:

public partial class MainWindow : Window
{
    public BindingList<Session> Sessions { get; } = new BindingList<Session>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void BtnTest_OnClick(object sender, RoutedEventArgs e)
    {
        Sessions.Add(new Session { Title = "test1", Host = "test2" });
    }
}

In WPF it isn't necessary to use BindingList, especially not when the element type implements INotifyPropertyChanged. ObservableCollection is more common:

public ObservableCollection<Session> Sessions { get; }
    = new ObservableCollection<Session>();

Upvotes: 2

Related Questions