Plata
Plata

Reputation: 45

Refreshing WPF DataView after replacing ObservableCollection

I have 3 methods that returns a List collection and I cannot change them.

    List<Person> GetListPerson()
    {
        List <Person> list = new List<Person>();
        list.Add(new Person { FirstName = "Judge", LastName = "Mental" });
        list.Add(new Person { FirstName = "Office", LastName = "Rocker" });
        list.Add(new Person { FirstName = "Sir", LastName = "Real" });

        return list;
    }

    List<Person> GetOnePerson()
    {
        List<Person> list = new List<Person>();
        list.Add(new Person { FirstName = "Josh", LastName = "Smith" });
        return list;
    }

    List<Person> ClearPerson()
    {
        List<Person> list = new List<Person>();
        return list;
    }

In my XAML I have a 3 buttons and a grid with binding to a observable collection

<Window x:Class="WpfApplication.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:WpfApplication"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <Button Name="GetList" Height="30" Content="GetList" Click="GetList_Click"  />
    <Button Name="GetOne" Height="30"  Content="GetOne" Click="GetOne_Click"/>
    <Button Name="Clear" Height="30" Content="Clear" Click="Clear_Click" />
    <DataGrid x:Name="dataGrid" Height="230" ItemsSource="{Binding}" />
</StackPanel>

This is the code behind:

private ObservableCollection<Person> _pObsList;
    public ObservableCollection<Person> PObsList
    {
        get { return _pObsList; }
        set { _pObsList = value;
            this.OnPropertyChanged("PObsList");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(
                this, new PropertyChangedEventArgs(propName));
    }

    public MainWindow()
    {
        InitializeComponent();
        PObsList = new ObservableCollection<Person>();
        dataGrid.DataContext = PObsList;
    }


    private void GetList_Click(object sender, RoutedEventArgs e)
    {
        PObsList = new ObservableCollection<Person>(GetListPerson());
    }

    private void GetOne_Click(object sender, RoutedEventArgs e)
    {
        PObsList = new ObservableCollection<Person>(GetOnePerson());
    }

    private void Clear_Click(object sender, RoutedEventArgs e)
    {
        PObsList = new ObservableCollection<Person>(ClearPerson());
    }

When the app is run, the grid will display the columns but no records as expected; but if clicking GetList button, my Observable collection will contain 3 elements, but the DataGrid will remain empty.

By reading other links, it seems that I need to implement PropertyChanged on the Collection, but I think something else is missing.

It is not possible to change the Lists to Observable collection and I am trying not to clear and add them manually.

Any idea or help?

Upvotes: 0

Views: 576

Answers (3)

Andreea Dumitru
Andreea Dumitru

Reputation: 96

If you put a breakpoint in your

public MainWindow()
{
    InitializeComponent();
    PObsList = new ObservableCollection<Person>();
    dataGrid.DataContext = PObsList;
}

you`ll see that PObsList is empty.

When you press GetList button, your list is not empty because your method GetListPerson return a list with values.

You can change to :

 public MainWindow()
    {
        InitializeComponent();
        PObsList = new ObservableCollection<Person>();
        PObsList.AddRange(GetPersonList());
        dataGrid.DataContext = PObsList;
    }

Upvotes: 0

Evert
Evert

Reputation: 354

I think the issue is the DataContext. When you change the PObsList in any of the 3 event handlers, you just set a new value for PObsList, the DataContext will remain the original PObsList. I suggest to use a separate object (a viewmodel) with an ObservableCollection property to use as DataContext, not an ObservableCollection directly.

Upvotes: 2

Piet Vredeveld
Piet Vredeveld

Reputation: 135

In the click handlers you override the PObsList variable. Clear the list and add the new items from the methods:

PObsList.Clear();
PObsList.AddRange(GetListPerson());

Upvotes: 0

Related Questions