Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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

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
XML
<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:


C#
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:


C#
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:


C#
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

 
Share this answer
 
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.
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900