Silverlight TreeView issue: Cannot set a CheckBox to IsCheck = true inside a TreeView

This are the steps to reproduce the problem, as you can see in the template the bindings are TwoWay still mmanually I cannot change the check box after the controls are bound.

The template is pretty simple, 2 levels with the same information, an image, a checkbox and a label.

 <UserControl.Resources>
        
        <common:HierarchicalDataTemplate x:Key="ChildrenTemplate" ItemsSource="{Binding Children, Mode=TwoWay}">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Path=Link}" Width="20" Height="20" />
                <CheckBox Tag="{Binding Path=Name}" Foreground="LightBlue" IsChecked="{Binding Path=IsThisChecked, Mode=TwoWay}" Checked="check_Checked" Unchecked="check_Unchecked" Margin="0,0,10,0" />
                <TextBlock FontSize="10" Text="{Binding Path=Name}"/>
            </StackPanel>
        </common:HierarchicalDataTemplate>
        
        <common:HierarchicalDataTemplate x:Key="RootFeaturesTemplate" ItemsSource="{Binding Path=ListChildren, Mode=TwoWay}" ItemTemplate="{StaticResource ChildrenTemplate}" >
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Path=Link}" Width="20" Height="20" />
                <CheckBox Tag="{Binding Path=Name}" Foreground="LightBlue" IsChecked="{Binding Path=IsThisChecked, Mode=TwoWay}" Checked="check_Checked" Unchecked="check_Unchecked" Margin="0,0,10,0" />
                <TextBlock FontSize="10" Text="{Binding Path=Name}"/>
            </StackPanel>
        </common:HierarchicalDataTemplate>
       
    </UserControl.Resources>

 

Creating the model for the items, difficult to recreate the information for the model.

for (int i = 0; i &lt; _mapService.Layers.Count(); i++)
            {
                   CIModel.CheckBoxEx temp = CreateCheckBoxEx(_mapService.Layers[i]);

                    if (_mapService.Layers[i].SubLayerIds != null &amp;&amp; _mapService.Layers[i].SubLayerIds.Length &gt; 0)
                    {
                        foreach (LayerInfo layerInfo in _mapService.Layers)
                        {
                            if ( _mapService.Layers[i].SubLayerIds.Contains(layerInfo.ID) == true )
                            {
                                CIModel.CheckBoxEx tempChild = CreateCheckBoxEx(layerInfo);
                                temp.ListChildren.Add(tempChild);
                                trackit.Add(layerInfo.ID);
                            }
                        }
                    }

                    if ( trackit.Contains(_mapService.Layers[i].ID) == false)
                        _layerNames.Add(temp);
                
            }

            TOCFeatures.ItemsSource = _layerNames;
 

Accessing the Checkbox IsChecked to set the checkboxes inside the template.

for (int p = 0; p &lt; treeView.Items.Count; p++)
            {
                CheckBoxEx pTemp = treeView.Items[p] as CheckBoxEx; 
                if (pTemp.Name == checkTemp.Tag.ToString())
                { 
                    if (pTemp.ListChildren != null &amp;&amp; pTemp.ListChildren.Count &gt; 0) 
                    { 
                        foreach (CheckBoxEx box in pTemp.ListChildren) 
                        { 
                            box.check.IsChecked = bIsCheck;
                            box.IsThisChecked = bIsCheck;                            
                        } 
                    } 
                }
            }
 
 

Solution

Looks like I found the solution finally. Implement the INotifyPropertyChanged interface to notify the TreeView that something has changed.

public class CheckBoxEx : INotifyPropertyChanged
    {
        public CheckBoxEx()
        {
            ListChildren = new List&lt;CheckBoxEx&gt;();
        }

        public string Name
        {
            get;
            set;
        }
        public CheckBox check
        {
            get;
            set;
        }
                
        public string Link
        {
            get;
            set;
        }
        private bool _IsThisChecked;
        public bool IsThisChecked
        {
            get
            {
                return _IsThisChecked;
            }
            set
            {
                _IsThisChecked = value;
                
                 if ( PropertyChanged != null )
                    PropertyChanged(_IsThisChecked, new PropertyChangedEventArgs("IsThisChecked"));
            }
        }

        public List&lt;CheckBoxEx&gt; ListChildren
        {
            get;
            set;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
 

Its important to notice that I check if the PropertyChanged is null as if the TreeView is not expanded, the item is not being bind yet. The new templates give the programmer lots of flexibility as much as headaches. Constructing and fitting your data to a model is harder than needed to be.

Cheers

Al

#1 b a r s » Blog Archive » Silverlight TreeView issue: Cannot set a CheckBox to IsCheck … on 4.18.2009 at 2:13 AM

Pingback from b a r s » Blog Archive » Silverlight TreeView issue: Cannot set a CheckBox to IsCheck …

#2 XAML Templates on 4.18.2009 at 11:44 PM

Hi, nice article take a look at the following address: http://www.xamltemplates.net where you can find themes/styles for WPF and Silverlight controls, check it out.