Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# WPF
Hi all,
 
I am wondering if i can get some visual update from ListView
 
when the data in it is changed.
 
I use the data binding with xaml and the code below.
 
this.DataContext = _processInfoList;
 
But when I change the data and call the InvalidateVisual(),
 
It doesn't update its visual appearence.
 

I kind of solve this problem by using
 
listView1.BeginInit();
listView1.EndInit();
 
instead of
 
InvalidateVisual();
 
BUT!!!
 
It cost too much the usage of cpu.
 
it is small listview and its cpu usage is like 20% when i call BeginInit();
 

I will be really glad to hear your opinion
 
Thanks,
pill.
Posted 14-Apr-10 17:01pm
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

If I understand correctly, you need to update your list when an item is addend or removed from the collection, right? This is simple to achieve with the use of an ObservableCollection instead of a List/Array

The trick is the use of the ObservableCollection because it implements the INotifyCollectionChanged interface, that is responsible for inform the Binding that the content of the collection has changed.

As for the code for achieve it is:

XAML
<Window x:Class="CollectionChangeQuestion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CollectionChangeQuestion"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView ItemsSource="{Binding Players}">
            <ListView.View>
                <GridView AllowsColumnReorder="True">
                    <GridViewColumn DisplayMemberBinding="{Binding FirstName}" Header="First Name"/>
                    <GridViewColumn DisplayMemberBinding="{Binding LastName}" Header="Last Name"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Position}" Header="Position"/>
                </GridView>
            </ListView.View>
        </ListView>
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Content="Add New" Click="AddNew_Click" Margin="5,2.5" Width="150"/>
        </StackPanel>
    </Grid>
</Window>
CS

The Player class:

public class Player : INotifyPropertyChanged
{
    private string _FirstName;
    private string _LastName;
    private string _Position;
 
    public string FirstName
    {
        get { return _FirstName; }
        set
        {
            if (_FirstName != value)
            {
                _FirstName = value;
                NotifyPropertyChanged("FirstName");
            }
        }
    }
 
    public string LastName
    {
        get { return _LastName; }
        set
        {
            if (_LastName != value)
            {
                _LastName = value;
                NotifyPropertyChanged("LastName");
            }
        }
    }
 
    public string Position
    {
        get { return _Position; }
        set
        {
            if (_Position != value)
            {
                _Position = value;
                NotifyPropertyChanged("Position");
            }
        }
    }
 
    #region INotifyPropertyChanged Members
 
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    #endregion
}

The ViewModel class:

public class ViewModel
{
    public ObservableCollection<Player> Players
    {
        get;
        private set;
    }
 
    public ViewModel()
    {
        Players = new ObservableCollection<Player>();
        #if DEBUG
        // Code for add dummy data if in debugging environment
        Players.Add(
            new Player
            {
                FirstName = "Raul",
                LastName = "Mainardi Neto",
                Position = "Me"
            });
        Players.Add(
            new Player
            {
                FirstName = "Maria Lúcia",
                LastName = "Kardosh de Freitas Mainardi",
                Position = "Wife"
            });
        Players.Add(
            new Player
            {
                FirstName = "Catarina",
                LastName = "de Freitas Mainardi",
                Position = "Daughter"
            });
        #endif
    }
}

The Window class:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
 
    private void AddNew_Click(object sender, RoutedEventArgs e)
    {
        var currentContext = this.DataContext as ViewModel;
        if (currentContext == null)
        {
            MessageBox.Show("The DataContext is not a ViewModel");
            return;
        }
 
        currentContext.Players.Add(
            new Player
            {
                FirstName = "Dummy",
                LastName = "Person",
                Position = "Not defined"
            });
    }
}

By using this approach you will not need to call neither the InvalidateVisual() (which is responsible for Invalidating the rendering of the element, and forces a complete new layout pass. OnRender is called after the layout cycle is completed.) or the BeginInit() (which is not performatic at all).

Hope this helps

All best

Raul Mainardi Neto

  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Hi, Raul.
 
I tried your suggestion but unfortunatly it was not an answer.
 
Maybe I wasn't quite clear about my problem to you.
 
I am developing an application that executes some other application
 
and show how much it costs the usage of cpu(s)
 
just like the task manager of the windows.
 
But your information was quite useful.
 
I am feeling i have to use INotifyProperyChanged someday.
 
Thants, pill.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 428
1 Sergey Alexandrovich Kryukov 253
2 PhilLenoir 115
3 RajeeshMenoth 110
4 Peter Leow 100
0 Sergey Alexandrovich Kryukov 6,465
1 OriginalGriff 5,926
2 CPallini 2,473
3 Richard MacCutchan 1,687
4 Abhinav S 1,540


Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 15 Apr 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100