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 < _mapService.Layers.Count(); i++) { CIModel.CheckBoxEx temp = CreateCheckBoxEx(_mapService.Layers[i]); if (_mapService.Layers[i].SubLayerIds != null && _mapService.Layers[i].SubLayerIds.Length > 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 < treeView.Items.Count; p++) { CheckBoxEx pTemp = treeView.Items[p] as CheckBoxEx; if (pTemp.Name == checkTemp.Tag.ToString()) { if (pTemp.ListChildren != null && pTemp.ListChildren.Count > 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<CheckBoxEx>(); } 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<CheckBoxEx> 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


