Im using a treeview control inside my usercontrol. Usercontrol is used in a MainWindow (just for test). DataContext of the MainWindow is my ViewModel. In usercontrol code-behind i set some DependencyProperty and everythings work fine, eccept a property that doesn't fire the callback. In ViewModel there is an ObservableCollection Tree. MyObject contains a property ObservableCollection Leafs. This is the tree structure i'm using to populate the TreeView.
If i pass Tree property to the usercontrol (usign a DependencyProperty Source), it works fine. I mean that if i change elements inside Tree in ViewModel, Source fires the notification and the TreeView is updated. If i pass Tree.Leafs.elementAt(0) CurrentTree to the usercontrol (using another DependencyProperty Root) the notification fires once only when the usercontrol is loaded. If i change CurrentTree, the notification in ViewModel works, but RootChanged() in UserControl is not raised. I don't understand why.
This is the code: MainWindow
<DockPanel>
<controls:TreeView Root="{Binding CurrentTree, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}">
</controls:TreeView>
</DockPanel>
ViewModel
private MyObject currentTree;
public MyObject CurrentTree
{
get
{
return currentTree;
}
set
{
if (currentTree == value) return;
currentTree = value;
NotifyPropertyChanged();
}
}
UserControl code behind
public static readonly DependencyProperty RootProperty = DependencyProperty.Register("Root", typeof(MyObject), typeof(TreeView), new FrameworkPropertyMetadata(new PropertyChangedCallback(RootChanged)));
private static void RootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TreeView)d).Root= (MyObject)e.NewValue;
}
public MyObject Root
{
get
{
return (MyObject)GetValue(RootProperty);
}
set
{
SetValue(RootProperty, value);
}
}
TreeView (UserControl) xaml
<UserControl x:Class="MyControls.TreeView"
x:Name="TreeViewUserControl"
.....
<TextBlock Text="{Binding Root.Key, ElementName=TreeViewUserControl }" Height="16"/>
.....
</UserControl>
The MainView DataContext is ViewModel, i suppose that the Datacontext of UserControl is inherited from MainView. The TextBlock in UserControl is used for test the DependencyProperty.
This is the XAML Binding debug:
System.Windows.Data Warning: 67 : BindingExpression (hash=14200498): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=14200498): Found data context element: TreeView (hash=49044892) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=14200498): Activate with root item ViewModel (hash=49218346)
System.Windows.Data Warning: 108 : BindingExpression (hash=14200498): At level 0 - for ViewModel.CurrentTree found accessor ReflectPropertyDescriptor(CurrentTree)
System.Windows.Data Warning: 104 : BindingExpression (hash=14200498): Replace item at level 0 with ViewModel (hash=49218346), using accessor ReflectPropertyDescriptor(CurrentTree)
System.Windows.Data Warning: 101 : BindingExpression (hash=14200498): GetValue at level 0 from ViewModel (hash=49218346) using ReflectPropertyDescriptor(CurrentTree): MyObject (hash=52380055)
System.Windows.Data Warning: 80 : BindingExpression (hash=14200498): TransferValue - got raw value MyObject (hash=52380055)
System.Windows.Data Warning: 89 : BindingExpression (hash=14200498): TransferValue - using final value MyObject (hash=52380055)
So, i don't understand why the DependencyPropertyCallback is fired once.
private BsonTree currentTree { get; set; }
toprivate BsonTree currentTree;
. And although perhaps obvious, butNotifyPropertyChanged();
usesCallerMemberNameAttribute
? – ClemensSetValue(RootProperty, ...)
directly. – Clemens