Как установить DataContext без очистки свойств зависимости? - PullRequest
1 голос
/ 11 января 2010

Я использую шаблон viewmodel, поэтому мой DataContext для моего пользовательского элемента управления на самом деле является оберткой viewmodel для реальных данных.

Мой пользовательский элемент управления может содержать иерархические экземпляры пользовательского элемента управления.

Я настроил DependencyProperty в пользовательском элементе управления для реального фрагмента данных, с надеждой на создание новой модели представления для этих данных, когда она будет установлена ​​посредством привязки, а затем установил для контекста данных пользовательского элемента управления новую модель представления. Однако кажется, что установка свойства DataContext приводит к тому, что мои реальные данные DependencyProperty становятся недействительными и устанавливаются в нуль. Кто-нибудь знает способ обойти это, или, вернее, правильный способ, которым я должен использовать viewmodels?

Подрезанные образцы того, что я пытаюсь сделать:

Пользовательский контроль:

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>

Эта проблема упоминалась в комментариях Невозможно связать данные DependencyProperty , но никогда не решалась

1 Ответ

1 голос
/ 11 января 2010

Делая это:

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

Вы связываете свое свойство Archetype со свойством Value в контексте данных.Изменяя ваш контекст данных на новый ArchetypeViewModel, вы фактически вызываете новую оценку привязки.Необходимо убедиться, что новый объект ArchetypeViewModel имеет ненулевое свойство Value.

Не видя больше вашего кода (в частности, определения ArchetypeComplexPropertyViewModel и ArchetypePropertyViewModel)не могу сказать, в чем причина этого.

...