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

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

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

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

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

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

ViewModelsCommand = "{Binding MyControl.MyCommand}"

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

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

0
Chris Nicol 30 Авг 2010 в 21:26
Как вы создаете / подключаете свои представления и модели просмотра?
 – 
Jay
30 Авг 2010 в 22:18
Для этого примера ... представления просто объявлены в XAML (корнем которого является окно), модели представления создаются в конструкторе представления
 – 
Chris Nicol
31 Авг 2010 в 00:25

3 ответа

Лучший ответ

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

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

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

      DataContext = viewModel;
 }

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

myControl.GetBindingExpression(MyControl.MyCommandProperty).UpdateSource();
1
Jay 1 Сен 2010 в 08:11
Джей, мне нравится этот подход, и я использую его для текущей проблемы. Однако все же хотелось бы решить проблему через привязку. Это должно быть возможно, и я считаю, что это был бы удобный подход, если бы это было возможно.
 – 
Chris Nicol
1 Сен 2010 в 07:04
Я обновляю ответ, добавляя дополнительную информацию об использовании привязки.
 – 
Jay
1 Сен 2010 в 08:11

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

0
JoshVarga 31 Авг 2010 в 08:32
Ага, и то, что я хочу достичь, не должно требовать того уровня сложности, который можно было бы добавить с помощью чего-то вроде Messenger. Я не говорю, что Messenger сложен, просто я просто хочу передать команду вниз по визуальному дереву.
 – 
Chris Nicol
31 Авг 2010 в 21:16

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

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

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

<local:MyControl 
         MyCommand="{Binding ViewModelsCommand,Mode=OneWayToSource}" /> 
0
HCL 31 Авг 2010 в 23:27
Да, но когда я это делаю, я получаю MyCommand - это ViewModelsCommand, а это не то, что я хочу. Я хочу, чтобы ViewModelsCommand была MyCommand. Имеет ли это смысл? Извините, если я плохо это объясняю
 – 
Chris Nicol
31 Авг 2010 в 01:36
Я удивлен таким поведением. Вы проверили, есть ли у вас старый тестовый код в коде программной части или в другом месте, которое переопределяет эту привязку? Может быть привязка, объявленная в коде, или даже статическое присвоение? Если проблема не в этом, создайте и прикрепите преобразователь значений, который ничего не делает, кроме возврата входного значения, а затем установите точку останова в двух методах преобразования. После этого вы увидите, когда какой объект перемещается откуда куда. У меня нет другой идеи. Насколько я понимаю, привязка должна делать именно то, что вы хотите, а не наоборот.
 – 
HCL
31 Авг 2010 в 01:55
1
Источник будет обновлен только в случае изменения целевого свойства, чего никогда не произойдет. Насколько мне известно, OneWayToSource не устанавливает источник при первоначальной привязке.
 – 
Jay
31 Авг 2010 в 19:38
1
И @Chris Nicol: Спасибо, я не знал об этом (очевидно :). Я удалю свой пост через несколько минут, чтобы не вести других людей в неверном направлении.
 – 
HCL
31 Авг 2010 в 22:41
2
Я бы оставил это. Это разумный подход; другие могут спросить, почему бы этого не сделать.
 – 
Jay
31 Авг 2010 в 23:07