Я знаю два способа, как это сделать.
1) Добавить новый класс, например, MainWindowViewModel
и добавить туда 2 команды и экземпляр UserControlViewModel
(выне сказал название, поэтому я буду называть его так).Вот часть примера:
public class MainWindowViewModel
{
public UserControlViewModel ChildControlViewModel { get; set; }
private Lazy<RelayCommand> nextCommand = new Lazy<RelayCommand>(() =>
new RelayCommand(
() => this.ChildControlViewModel.CollectionView.MoveCurrentToNext(),
() => this.ChildControlViewModel.CollectionView.CurrentPosition < this.ChildControlViewModel.ItemTypes.Count - 1));
public ICommand NextCommand
{
get { return nextCommand.Value; }
}
//prev command...
}
Я использовал класс Lazy
, но основная идея ясна: код тот же, за исключением вызова this.ChildControlViewModel.CollectionView
вместо CollectionView
.
2) Используйте класс Messenger
.
Этот способ не так очевиден и имеет только одно преимущество: модели представления слабо связаны.
public class MainWindowViewModel
{
public const string NextCommandNotification = "NextCommand";
public const string PreviousCommandNotification = "PreviousCommand";
private bool isNextCommandEnabled;
private bool isPreviousCommandEnabled;
public MainWindowViewModel()
{
this.NextCommand = new RelayCommand(
() => Messenger.Default.Send(new NotificationMessage<MainWindowViewModel>(this, NextCommandNotification)),
() => this.isNextCommandEnabled);
//prev command...
Messenger.Default.Register<NotificationMessage<UserControlViewModel>>(this,
msg =>
{
if (msg.Notification == UserControlViewModel.CurrentItemChangedNotification)
{
this.isNextCommandEnabled = msg.Content.CollectionView.CurrentPosition < msg.Content.ItemTypes.Count - 1;
this.NextCommand.RaiseCanExecuteChanged();
//prev command...
}
});
}
public ICommand NextCommand { get; private set; }
//prev command...
}
public class UserControlViewModel
{
public const string CurrentItemChangedNotification = "CurrentItemChanged";
public UserControlViewModel()
{
Messenger.Default.Register<NotificationMessage<MainWindowViewModel>>(this,
msg =>
{
if (msg.Notification == MainWindowViewModel.NextCommandNotification)
this.CollectionView.MoveCurrentToNext();
else if (msg.Notification == MainWindowViewModel.PreviousCommandNotification)
this.CollectionView.MoveCurrentToPrevious();
});
this.CollectionView.CurrentChanged += (s,e) => Messenger.Default.Send(new NotificationMessage<UserControlViewModel>(this, CurrentItemChangedNotification))
}
}
Я не уверен, будет ли этот код работать правильно.И это не легко объяснить.
Класс MainWindowViewModel
отправляет сообщение, когда пользователь нажимает кнопку.Класс UserControlViewModel
обрабатывает сообщение, изменяет позицию текущего элемента и отправляет сообщение CurrentItemChangedNotification
.Класс MainWindowViewModel
обрабатывает это сообщение и обновляет часть команды CanExecute
.
1-е решение лучше для меня, но в то же время я довольно часто использую класс Messenger
.Это зависит от ситуации.