WPF MVVM Исключение при регистрации UserControl в DataContext

Я новичок в MVVM и стараюсь следовать всем рекомендациям, которые я нахожу, чтобы уважать его. Я хотел бы использовать Busy-Animation на одном из моих пользовательских контроллеров. Я хочу включить его в элемент управления вот так.

Пользовательский контроль, в который он вложен, показан в MainWindow с использованием DataTemplate для ViewModel, например, так:

<Window.Resources>
    <DataTemplate DataType="{x:Type AppViews:AppConfigViewModel}">
        <local:AppConfigView />
    </DataTemplate>
</Window.Resources>

<Grid>
    <ContentControl Content="{Binding CurrentPageViewModel}" />
</Grid>

При запуске этого приложения отображается приложение, и я также вижу представление для AppConfigViewModel, которое правильно привязано, поскольку базовые значения отображаются правильно в представлении.

Теперь я попытался зарегистрировать Busy-Animation в ViewModel (чтобы управлять им оттуда), выполнив это в конструкторе BusyAnimation:

(DataContext as PageViewModel).BusyAnim = this;

По какой-то причине DataContext всегда имеет значение null, и результат этой строки является исключением. Что я здесь не так делаю?

1 ответ

Решение

То, что я пытался сделать, противоречит идее MVVM. Я пытался снизить значение объекта, который должен быть общим.

Лучшим подходом к задаче, которую я пытался достичь, является реализация свойств зависимостей в компоненте занятой анимации. Они предназначены для привязки к модели представления в основном отображаемого представления. таким образом, анимация занятости может быть показана, когда изменяется какое-либо свойство в модели представления. Это может быть, например, bool с именем "работает".

это код свойства зависимости в моей занятой анимации:

public static readonly DependencyProperty ShowBusyProperty = DependencyProperty.Register("ShowBusy", typeof(Boolean), typeof(FortschrittView), new PropertyMetadata(false, OnShowBusyPropertyChanged));
public Boolean ShowBusy
{
    get { return (Boolean)this.GetValue(ShowBusyProperty); }
    set { this.SetValue(ShowBusyProperty, value); }
}

private static void OnShowBusyPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    FortschrittView myUserControl = dependencyObject as FortschrittView;
    myUserControl.OnPropertyChanged("ShowBusy");
    myUserControl.OnShowBusyPropertyChanged(e);
}
private void OnShowBusyPropertyChanged(DependencyPropertyChangedEventArgs e)
{
    if(ShowBusy)
    {
        Start();
    }
    else
    {
        Stop();
    }
}

Да, это много кода, но я чувствую, что wpf так хочет. Помните, что код выше находится в пользовательском элементе управления busy-animation и запускает функции Start() Stop(), которые управляют раскадровками.

Ниже xaml находится в элементе управления, который использует busyanimation, привязывая его к модели представления, для которой анимация занятости должна указывать фоновую работу для:

 <local:BusyAnimation ShowBusy="{Binding Model.IsBusy}"/>

Это свойство ShowBusy - это свойство зависимости, реализованное выше. Конечно, IsBusy из модели должен следовать наблюдаемой модели, чтобы все работало.

/ PS: я подробно документировал ошибки, которые я сделал и как я их решал. Могу ли я избавиться от негативных моментов, которые я получил как-то за создание этого вопроса?

Другие вопросы по тегам