Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ListView: Howto refresh manually?

I have a binding problem with the WPF ListView. The view model implements INotifyPropertyChanged to get triggered on data updates. But it contains an observable collection of a type ("Person") that does NOT implement INotifyPropertyChanged.

The ListView shows up my bound persons after startup, that is fine. But after having changed the model's data (person's age), I somehow need to manually update the visual representation/binding - here's my problem.

I would appreciate if someone could kick me into the right direction, thank you!

The model is really simple:

// does not implement INotifyPropertyChanged interface
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

The PersonList is an ObservableCollection that is bound via ItemsSource to the ListView:

<ListView x:Name="ListViewPersons" ItemsSource="{Binding PersonList}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
                <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

The view's codebehind delegates the "age growing" to the viewmodel. After this change in the model's data, I need to update the GUI somehow, and here's my problem:

private void Button_Click(object sender, RoutedEventArgs e)
    {
           ...

            // increasing the age of each person in the model 
            viewModel.LetThemGetOlder();

            **// how to update the View?**

            // does not work
            ListViewPersons.GetBindingExpression(ListView.ItemsSourceProperty)
                                 .UpdateTarget();

            // does not work either
            ListViewPersons.InvalidateProperty(ListView.ItemsSourceProperty);
        }
    }

To be complete, the ViewModel:

class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        PersonList = new ObservableCollection<Person>
            {
                new Person {Name = "Ellison", Age = 56},
                new Person {Name = "Simpson", Age = 44},
                new Person {Name = "Gates", Age = 12},
            };
    }

    internal void LetThemGetOlder()
    {
        foreach (var p in PersonList)
        {
            p.Age += 35;
        }
    }

    private ObservableCollection<Person> _personList;
    public ObservableCollection<Person> PersonList
    {
        get { return _personList; }
        set
        {
            _personList = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
like image 604
John Avatar asked Dec 06 '25 06:12

John


1 Answers

You can try Items.Refresh(); but i would reconsider my class design, especially your viewmodel and models. Why don't your models implement INotifyPropertyChanged? Why don't you wrap your models in view models on a 1:1 basis? Currently you are working around WPF and you should only do that if you have a good reason.

like image 168
dowhilefor Avatar answered Dec 08 '25 00:12

dowhilefor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!