views:

58

answers:

2

I copied the basic method of having checkbox in a treeview from the official Silverlight toolkit Checkboxes in a TreeView example.

When a user clicks on a parent TreeViewItem I want all of the child items to be checked, as in the above example. This works fine when the parent is collapsed, clicking the checkbox puts a tick in the parent and when you expand the node all children have a tick in the checkbox.

However it doesn't work if the parent is expanded. None of the children are updated to have a tick in the checkbox, although the underlying data list is updated.

My XAML is as follows:

<sdk:HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding Path=Contracts}">
    <StackPanel Orientation="Horizontal" ToolTipService.ToolTip="{Binding Path=Name}">
        <CheckBox IsTabStop="False" IsThreeState="{Binding Path=HasContracts}" IsChecked="{Binding Path=Selected, Mode=TwoWay}" Click="CheckBox_Click" />
        <TextBlock Text="{Binding Path=Name}" Tag="{Binding Path=ID}"/>
    </StackPanel>
</sdk:HierarchicalDataTemplate>

    <sdk:TreeView x:Name="tvClientContract" ItemsSource="{Binding Path=ClientContracts, Mode=TwoWay}" ItemTemplate="{StaticResource NodeTemplate}"/>

This is bound to a List<ClientContract> and uses the same code behind as in the linked example.

The ClientContract object is:

public int ID { get; set; }
public string Name { get; set; }
public List<ClientContract> Contracts { get; set; }
public bool? Selected { get; set; }

How can I force the child to repaint itself as the underlying List<ClientContract> object is updated?

A: 

Try using ObservableCollection<ClientContract> instead of a List<>. Usually you want to databind to this collection type instead when the data is dynamic so it can notify the UI of collection changes.

Dan Auclair
Just tried it, no difference I'm afraid. I'm implementing INotifyPropertyChange within my VM. As I said the value in the actual List is being set, it's just that the UI isn't updating.
Fermin
+1  A: 

If you want to use INotifyPropertyChange(what I did instead of using ObservableCollection) here is how you do it per example on the ID element:

public class myclass : INotifyPropertyChanged
{
    private int id_Value;
    public int ID
    {
        get { return id_Value; }
        set
        {
            id_Value = value;
            NotifyPropertyChanged("ID");
        }
    }

    public string Name { get; set; }
    public List<ClientContract> Contracts { get; set; }
    public bool? Selected { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

I hope this helps if it was what you were trying to do.

Ephismen
I was raising a NotifyPropertyChanged event on the collection as a whole, not the individual properties. Thanks.
Fermin