Ответ 1
Если вы хотите использовать грязное решение MVVM, затем установите Tag = "{Binding}" на кнопку и обработайте событие Click. В обработчике событий вызовите команду на ViewModel.
Я просмотрел эту сеть и Google, и решения не сработали для меня.
У меня есть команда в ViewModel UserControl. Ну, в Usercontrol есть элемент ItemsControl, привязанный к ObservableCollection. Внутри DataTemplate элемента ItemsControl.ItemTemplate у меня есть кнопка, и я хочу использовать эту команду. Я не могу связать команду, потому что внутри DataTemplate datacontext не является ViewModel, а элементом ObservableCollection.
Возникает вопрос: как я могу привязать кнопку к команде, если потерял родительский datacontext?
Я думаю, что для этого нужно иметь легкое решение, потому что я считаю, что это общая проблема.
Представьте себе этот сценарий:
У вас есть элемент ListBox с наблюдаемым символом в виде ItemsSource, поэтому вы используете таблицу данных внутри ListBox для каждого элемента коллекции. Ну, вы хотите удалить выбранный элемент, и вы помещаете кнопку в каждую строку для этой работы. ¿Как вы это делаете?
В MVP я могу сделать это в событии нажатия кнопки:
Button but = e.Source as Button;
if (but != null)
Presenter.ActualNote = but.DataContext as Note;
Короче. Вы отправляете datacontext строки (выбранный элемент) ведущему.
Но как я могу сделать это в режиме mvvm? Поскольку мне нужно использовать команду, но я не могу назначить ей кнопку, потому что кнопка ничего не знает о ViewModel (где существует команда).
Как вы можете видеть, кнопка должна существовать внутри шаблона данных, тогда datacontext больше не является ViewModel. Вот почему мне нужен доступ к родительскому DataContext для доступа к команде.
Я надеюсь, что вы лучше поймете мою проблему.
Спасибо.
Если вы хотите использовать грязное решение MVVM, затем установите Tag = "{Binding}" на кнопку и обработайте событие Click. В обработчике событий вызовите команду на ViewModel.
Используйте приведенную ниже привязку для команды кнопки:
{Binding DataContext.CommandName,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type MyUserControl}}}
Это скажет, чтобы найти ваш UserControl и использовать его DataContext.
RelativeSource работает, но я не думаю, что это право позволять элементам управления прокручивать свойства друг друга. Странно, что кнопка, помещенная внутри представления элемента, делает что-то с внешним источником данных, а не с связанным элементом. Возможно, вам придется просмотреть дизайн программных кодов.
Итак, как насчет изменения вашего класса элементов данных, чтобы он имел свойство, ссылающееся на весь вид модели?
Если ваш ItemSource имеет тип ObservableCollection<DataItem>
, то измените тип DataItem следующим образом:
public class DataItem
{
public BusinessObject Value { get; set; }
private ModelView modelView;
public ModelView ModelView
{
get
{
return modelView;
}
}
public DataItem(ModelView modelView)
{
this.modelView = modelView;
}
}