How to set DataContext without clearing dependency properties?
I'm using a viewmodel pattern, so my DataContext for my custom user control is actually a viewmodel wrapper for the real data.
My custom control can contain hierarchal instances of the custom control.
I set up a DependencyProperty in the custom control for the real piece of data, with the hopes of creating a new viewmodel for that data when it gets set via binding, and then setting the user control's datacontext to the new viewmodel. However, it seems that setting the DataContext property causes my real data DependencyProperty to become invalidated and set to null. Anyone know a way around this, or rather a proper way I should be using viewmodels?
Trimmed samples of what I'm trying to do:
The user control:
public partial class ArchetypeControl : UserControl
{
public static readonly DependencyProperty ArchetypeProperty = DependencyProperty.Register(
"Archetype",
typeof(Archetype),
typeof(ArchetypeControl),
new PropertyMetadata(null, OnArchetypeChanged)
);
ArchetypeViewModel _viewModel;
public Archetype Archetype
{
get { return (Archetype)GetValue(ArchetypeProperty); }
set { SetValue(ArchetypeProperty, value); }
}
private void InitFromArchetype(Archet开发者_开发知识库ype newArchetype)
{
if (_viewModel != null)
{
_viewModel.Destroy();
_viewModel = null;
}
if (newArchetype != null)
{
_viewModel = new ArchetypeViewModel(newArchetype);
// calling this results in OnArchetypeChanged getting called again
// with new value of null!
DataContext = _viewModel;
}
}
// the first time this is called, its with a good NewValue.
// the second time (after setting DataContext), NewValue is null.
static void OnArchetypeChanged( DependencyObject obj, DependencyPropertyChangedEventArgs args )
{
var control = (ArchetypeControl)obj;
control.InitFromArchetype(args.NewValue as Archetype);
}
}
The viewmodel:
class ArchetypeComplexPropertyViewModel : ArchetypePropertyViewModel
{
public Archetype Value { get { return Property.ArchetypeValue; } }
}
The XAML:
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding ViewModelType}" Value="{x:Type c:ArchetypeComplexPropertyViewModel}">
<Setter Property="Template" Value="{StaticResource ComplexPropertyTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="ComplexPropertyTemplate" TargetType="{x:Type TreeViewItem}">
<Grid>
<c:ArchetypeControl Archetype="{Binding Value}" />
</Grid>
</ControlTemplate>
This problem was mentioned in the comments of Cannot databind DependencyProperty but never resolved
By doing this:
<c:ArchetypeControl Archetype="{Binding Value}" />
You are binding your Archetype
property to the property called Value
on your data context. By changing your data context to the new ArchetypeViewModel
you effectively cause a new evaluation of the binding. You need to make sure that the new ArchetypeViewModel
object has a non-null Value
property.
Without seeing the more of your code (specifically, the definitions of ArchetypeComplexPropertyViewModel
and ArchetypePropertyViewModel
) I can't really say what is the cause of this.
精彩评论