views:

170

answers:

1

Hi everybody. First of all, I've to admin that I'm absolutely new to WPF! I think I've a problem with WPF Bindings or "PropertyChanged" notifications...

I have this XAML with a TextBlock and a listView

<StackPanel Orientation="Horizontal">
                        <TextBlock Margin="2" Name="UpdatesOperationResultcaption" Text="Operation result:" FontSize="12" Foreground="SteelBlue" Grid.Column="1" Height="21" VerticalAlignment="Top" TextAlignment="Left" />
                        <TextBlock Margin="2" Name="UpdatesOperationResult" Text="{Binding Path=viewModelData.UploadProgressText}" FontSize="12" Foreground="SteelBlue" Grid.Column="1" Height="21" VerticalAlignment="Top" TextAlignment="Left" Width="134.431" />
                    </StackPanel>
                    <ListView Grid.Column="1" Margin="1" ItemsSource="{Binding Path= viewModelData.MyPendingTasks, diag:PresentationTraceSources.TraceLevel=High}" Name="TasksListView" SelectionMode="Multiple" BorderThickness="1" FontSize="11" Height="110" SelectionChanged="TasksListView_SelectionChanged">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Task to execute" Width="350" DisplayMemberBinding="{Binding Path=taskFriendlyName,Converter={StaticResource debugConverter}, diag:PresentationTraceSources.TraceLevel=High}" />
                                <GridViewColumn Header="Value" Width="60" DisplayMemberBinding="{Binding Path=taskValuetoShow}" />
                            </GridView>
                        </ListView.View>
                    </ListView>

Then in the code behind I have this class which should manage the data to be shown...

public class ViewModelData : INotifyPropertyChanged
{
    int dummy = 0;
    private string uploadProgressString;
    private List<TaskToAccomplish> myPendingTasks = new List<TaskToAccomplish>();

    public ViewModelData()
    {
        uploadProgressString = "0 %";
        TaskToAccomplish tempTask = new TaskToAccomplish("TEST", "99 %", 0, "dummy", "dummy");
        myPendingTasks.Add(tempTask);
        tempTask = new TaskToAccomplish("TEST2", "100 %", 0, "dummy", "dummy");
        myPendingTasks.Add(tempTask);
    }

    public string UploadProgressText
    {
        get
        {
            return this.uploadProgressString;
        }
        set
        {
            if (value != this.uploadProgressString)
            {
                this.uploadProgressString = value;
                NotifyPropertyChanged("UploadProgressText");
            }
        }
    }

    public List<TaskToAccomplish> MyPendingTasks
    {
        get
        {
            return myPendingTasks;
        }
        set
        {
            myPendingTasks.Clear();
            foreach (TaskToAccomplish task in value)
            {
                myPendingTasks.Add(task);
            }

            NotifyPropertyChanged("MyPendingTasks");
            NotifyPropertyChanged("taskFriendlyName");
            NotifyPropertyChanged("taskValuetoShow");


            uploadProgressString = dummy.ToString();
            NotifyPropertyChanged("UploadProgressText");
            dummy++;

        }
    }

    protected void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

This is my situation: in the class constructor i put a couple of fake items just to show something on the screen (and possibly debug the bindings). At startup everything is fine. when I update my data setting a new value to the list the textblock bound to the uploadProgressString filed gets updated, while the listview is unaffected. in the output window I see that the PropertyChanged event reaches the ListView:

System.Windows.Data Warning: 91 : BindingExpression (hash=17842833): Got PropertyChanged event from ViewModelData (hash=8442299) System.Windows.Data Warning: 97 : BindingExpression (hash=17842833): GetValue at level 1 from ViewModelData (hash=8442299) using RuntimePropertyInfo(MyPendingTasks): List1 (hash=63249743 Count=2) System.Windows.Data Warning: 76 : BindingExpression (hash=17842833): TransferValue - got raw value List1 (hash=63249743 Count=2) System.Windows.Data Warning: 85 : BindingExpression (hash=17842833): TransferValue - using final value List`1 (hash=63249743 Count=2)

But nothing about the GridViewColumn. Everytime thie event is risen my list getter is invoked, nevertheless the listview is not updated with the new values. Where's my mistake? Thankyou

A: 

Please clarify your bindings. Two use viewModelData.XXX, two use XXX directly. What is the DataContext ?

And when a list is bound, use an ObservableCollection<>, not a List<>. When a list is bound, WPF looks for INotifyCollectionChanged (which List does not implement), not for INotifyPropertyChanged (well, it can use it, but for the list itself, not for the items in the list).

Timores
My application is a mess of thread and using ObservableCollection was almost impossible... that's why I decided to go for a List. Now I'll try to implement INotifyCollectionChanged, I'll let you know!
damiano