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: я подробно документировал ошибки, которые я сделал и как я их решал. Могу ли я избавиться от негативных моментов, которые я получил как-то за создание этого вопроса?