【问题标题】:How to set DataContext without clearing dependency properties?如何在不清除依赖属性的情况下设置 DataContext?
【发布时间】:2011-01-03 16:42:01
【问题描述】:

我使用的是视图模型模式,因此我的自定义用户控件的 DataContext 实际上是真实数据的视图模型包装器。

我的自定义控件可以包含自定义控件的分层实例。

我在自定义控件中为真实数据设置了一个 DependencyProperty,希望在通过绑定设置该数据时为该数据创建一个新的视图模型,然后将用户控件的数据上下文设置为新的视图模型。但是,似乎设置 DataContext 属性会导致我的真实数据 DependencyProperty 失效并设置为 null。任何人都知道解决这个问题的方法,或者更确切地说我应该使用视图模型的正确方法?

我正在尝试做的修剪样本:

用户控件:

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(Archetype 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);
    }
}

视图模型:

class ArchetypeComplexPropertyViewModel : ArchetypePropertyViewModel
{
    public Archetype Value { get { return Property.ArchetypeValue; } }
}

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>

这个问题在Cannot databind DependencyProperty的cmets中提到过,但一直没有解决

【问题讨论】:

标签: wpf datacontext invalidation dependency-properties


【解决方案1】:

通过这样做:

<c:ArchetypeControl Archetype="{Binding Value}" />

您将Archetype 属性绑定到数据上下文中名为Value 的属性。通过将数据上下文更改为新的ArchetypeViewModel,您可以有效地对绑定进行新的评估。您需要确保新的 ArchetypeViewModel 对象具有非空的 Value 属性。

没有看到更多的代码(特别是ArchetypeComplexPropertyViewModelArchetypePropertyViewModel 的定义),我真的不能说这是什么原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 2021-08-31
    • 2012-03-07
    相关资源
    最近更新 更多