У меня есть следующая ICommand в моем главном окне ViewModel.Как программно отправить команду
RelayCommand busyIndicatorCommand;
public ICommand BusyIndicatorCommand
{
get
{
if (busyIndicatorCommand == null)
busyIndicatorCommand = new RelayCommand(BusyIndicatorCommandExecute, CanBusyIndicatorCommand);
return busyIndicatorCommand;
}
}
Чтобы вызвать что-то подобное из детского представления, это простой процесс, когда в XAML есть кнопка.
<Button Content="Press Me"
Command="{Binding DataContext.BusyIndicatorCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding EnableIndicator}"/>
Я хотел был бы сделать то же самое, за исключением моего ViewModel и нет кнопки. Как мне это сделать?
[EDIT] Окончательное решение
создал новый проект класса
namespace Libs_SharedCommands
{ public class Commands
{
public enum CommandType
{
BusyIndicator
}
public static RoutedCommand cmd_BusyIndicator = new RoutedCommand();
}
}
Добавлена ссылка на него в моей модели представления управления пользователя и выполнить его следующим образом.
namespace UserControls
{
class UserControlViewModel
{
public UserControlViewModel()
{
setBusyIndicator(true);
Task.Factory.StartNew(() =>
{
//Do stuff here
})
.ContinueWith(t =>
{
Application.Current.Dispatcher.Invoke(new Action(() => setBusyIndicator(false)));
});
}
private void setBusyIndicator(bool enable)
{
Libs_SharedCommands.Commands.cmd_BusyIndicator.Execute(enable, null);
}
}
}
И, наконец, добавлены обработчики RoutedCommand в мое главное окно. Вид, который в свою очередь вызывает главное окно ViewModel. Довольный этим, и MVVM все еще нетронутым.
namespace Application
{
public partial class MainView
{
public MainView()
{
InitializeComponent();
CommandBinding cbBusyIndicator = new CommandBinding(Libs_SharedCommands.Commands.cmd_BusyIndicator, BusyIndicator_MainNavCmdExecute, MainNavCmdCanExecute);
this.CommandBindings.Add(cbBusyIndicator);
}
private void BusyIndicator_MainNavCmdExecute(object sender, ExecutedRoutedEventArgs e)
{
setCommand(Libs_SharedCommands.Commands.CommandType.BusyIndicator, e.Parameter);
}
private void MainNavCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void setCommand(Libs_SharedCommands.Commands.CommandType view_type, object parameter)
{
var viewModel = (MainViewModel)DataContext;
if (viewModel != null)
{
switch (view_type)
{
case Libs_SharedCommands.Commands.CommandType.BusyIndicator:
viewModel.ShowBusyIndicator = Convert.ToBoolean(parameter);
break;
default:
break;
}
}
}
}
}
К сожалению следовало бы сказать, что мнение ребенка/ViewModel в другом проекте, и загружается в главное окно с отражением. Поэтому при использовании кнопки, которую я угадываю, поскольку я не знаю точно, как она работает, но она использует визуальное дерево для поиска окна, тогда он находит ICommand в модели просмотра окон. Таким образом, он не знает, есть ли там BusyIndicatorCommand. Поэтому я не могу просто использовать BusyIndicatorCommand.Execute. Пожалуйста, дайте мне знать, если это неясно, моя терминология может отсутствовать! – Hank
@Hank: Но в том месте, где вы хотите вызвать команду, это тип с 'BusyIndicatorCommand' в области видимости? Если это так, вы можете использовать оператор 'as', чтобы попытаться применить DataContext к этому типу, и если это будет успешным, обратитесь к' BusyIndicatorCommand'. –
BusyIndicator не входит в объем. Можно ли что-то сделать свободно? – Hank