Search code examples
c#wpfrefreshitemscontrol

refresh bindings in itemscontrol wpf


i have a simple itemscontrol binding to a list of Entries object. The button updates the LastUpdated of each item in the List. How do I raise property changed event so that LastUpdated field is updated in the ItemsControl. I have simplified my example just to figure out the binding issue. My real sample uses PRISM and third party controls.

C# Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;

namespace TestItemsControl
{
    public class Entry
    {
        public string Name { get; set; }

        public DateTime LastUpdated { get; set; }
    }
}

namespace TestItemsControl
{
    public class TestViewModel: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public List<Entry> Entries { get; set; }

        public ICommand UpdateCmd { get; set; }

        public TestViewModel()
        {
            this.Entries = new List<Entry>();
            this.Entries.Add(new Entry{ Name = "1", LastUpdated = DateTime.Now });
            this.Entries.Add(new Entry { Name = "2", LastUpdated = DateTime.Now });
            this.Entries.Add(new Entry { Name = "3", LastUpdated = DateTime.Now });
        }

        public void Refresh()
        {
            if (this.PropertyChanged!= null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Entries"));
            }
        }
    }
}

XAML:

<Application x:Class="TestItemsControl.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestItemsControl"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:TestViewModel x:Key="viewModel"/>
    </Application.Resources>
</Application>


<Window x:Class="TestItemsControl.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:TestItemsControl"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" DataContext="{StaticResource viewModel}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Row="0" ItemsSource="{Binding Entries}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding Name}"/>
                        <TextBlock Text="{Binding LastUpdated}"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Grid.Row="1" Content="Update" Click="Button_Click"/>
    </Grid>
</Window>

Solution

  • You have to Check for Null if noone subscribes to the Event

    public class Entry : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string Name { get; set; }
    
        DateTime lastUD;
        public DateTime LastUpdated
        {
            get
            {
                return lastUD;
            }
            set
            {
                lastUD = value;
                if(PropertyChanged != NULL)
                   PropertyChanged(this, new PropertyChangedEventArgs("LastUpdated"));
            }
        }
    }