Выполнить команду usercontrol из модели представления

У меня есть пользовательский элемент управления с командой, и я хотел бы выполнить эту команду из содержащей ViewModel представления.

Это было бы легко сделать в коде позади, так как я мог бы просто ввести «UserControl.MyCommand.Execute», но, конечно, я хочу иметь возможность сделать это в ViewModel.

Теоретически я хотел бы связать команду UserControl с командой в ViewModel, которую я могу выполнить, а затем будет обрабатываться UserControl. Что-то вроде этого:

...
<local:MyControl
         MyCommand="{Binding ViewModelsCommand}" />
...

Конечно, это будет иметь эффект, противоположный тому, что я хочу сделать, так как теперь ViewModelsCommand привязан к MyCommand. Итак, как инвертировать это?

В основном я хочу иметь возможность связать что-то вроде этого:

ViewModelsCommand="{Привязка MyControl.MyCommand}"

Любые идеи или вдохновение будут приветствоваться, я не вижу обязательного режима, который позволил бы мне это сделать. И я не уверен, как получить доступ к свойствам DataContext для привязки (обычно вы просто делаете привязку и двустороннюю обработку, но, конечно, в этом сценарии это не работает).

Заранее спасибо.


person Chris Nicol    schedule 30.08.2010    source источник
comment
Как вы создаете/подключаете свои представления и модели представлений?   -  person Jay    schedule 30.08.2010
comment
Ради этого примера... представления просто объявлены в XAML (корень которого является окном), модели представления создаются в конструкторе представления   -  person Chris Nicol    schedule 31.08.2010


Ответы (3)


Вы создаете экземпляр модели представления в конструкторе представления.

Почему бы не установить значение явно при построении?

 public SomeView()
 {
      var viewModel = new SomeViewModel();
      viewModel.ViewModelCommand = MyCommand; // or = myControl.MyCommand

      DataContext = viewModel;
 }

Можно использовать привязку с OneWayToSource, TwoWay или Explicit, но вам все равно придется явно обновить исходный код хотя бы один раз в коде (всегда, если вы используете Explicit).

myControl.GetBindingExpression(MyControl.MyCommandProperty).UpdateSource();
person Jay    schedule 31.08.2010
comment
Джей, мне нравится этот подход, и я реализую его для текущей проблемы. Однако все же хотелось бы решить проблему через привязку. Это должно быть возможно, и я считаю, что это был бы удобный подход, если бы это было так. - person Chris Nicol; 01.09.2010
comment
@Chris Я обновляю ответ, добавляя дополнительную информацию об использовании привязки. - person Jay; 01.09.2010

Я использую EventAggregator PRISM или Messenger MVVMLight, чтобы позволить двум моделям ViewModel общаться, но ваш случай выглядит немного иначе, когда у вас есть представление (UserControl), разговаривающее с ViewModel.

person JoshVarga    schedule 31.08.2010
comment
Да, и то, что я хочу сделать, не должно нуждаться в уровне сложности, который был бы добавлен с помощью чего-то вроде Messenger. Я не говорю, что Messenger сложен, просто я хочу передать команду вниз по визуальному дереву. - person Chris Nicol; 31.08.2010

Обратите внимание, что следующий ответ неверен. Кажется, что OneWayToSource обновляется только после изменения целевого свойства. Однако я не удаляю этот ответ, чтобы сообщить другим людям, которые не знают об этом (например, мне).

Старый ответ (см. текст выше)

IMO, ваш пример должен работать (если MyControl.MyCommand является общедоступным свойством, которое возвращает ICommand). Вы пробовали BindingMode OneWayToSource?

<local:MyControl 
         MyCommand="{Binding ViewModelsCommand,Mode=OneWayToSource}" /> 
person HCL    schedule 30.08.2010
comment
Да, но когда я это делаю, я получаю, что MyCommand is ViewModelsCommand, а это не то, что мне нужно. Я хочу, чтобы ViewModelsCommand был MyCommand. Имеет ли это смысл? Извините, если я плохо объясняю это - person Chris Nicol; 31.08.2010
comment
Я удивлен таким поведением. Вы проверили, есть ли у вас старый тестовый код в коде программной части или в другом месте, который переопределяет эту привязку? Может быть Binding объявлен в коде или даже статическим присваиванием? Если это не проблема, создайте и присоедините преобразователь значений, который ничего не делает, кроме как возвращает входное значение, а затем установите точку останова в двух методах преобразования. После этого вы увидите, когда какой объект перемещается откуда куда. У меня нет другой идеи. Насколько я понимаю, Binding должен делать именно то, что вы хотите, а не наоборот. - person HCL; 31.08.2010
comment
@HCL Источник будет обновляться только в том случае, если целевое свойство изменится, чего никогда не произойдет. Насколько я знаю, OneWayToSource не устанавливает источник при первоначальной привязке. - person Jay; 31.08.2010
comment
Извините, HCL, Джей прав, OneWayToSource не работает для меня таким образом. Я пытался придумать способ объяснить это лучше, но я думаю, что это в основном команды Daisy Chaining?!?! - person Chris Nicol; 31.08.2010
comment
@Jay и @Chris Никол: Спасибо, я не знал об этом (очевидно:). Я удалю свой пост через несколько минут, чтобы не вести других людей в неправильном направлении. - person HCL; 31.08.2010
comment
@HCL Я бы оставил это. Это разумный подход; другие могут задаться вопросом, почему бы не сделать это. - person Jay; 31.08.2010
comment
Спасибо, что не удалили HCL, это была хорошая попытка. Я рад, что это для ясности и помощи другим. - person Chris Nicol; 01.09.2010