Использование родительского DataContext (привязка команды динамического меню WPF)

Я просмотрел эту сеть и google, и решения не работали для меня.

У меня есть команда на ViewModel UserControl. Ну, у usercontrol есть ItemsControl, привязанный к ObservableCollection. Внутри DataTemplate ItemsControl.ItemTemplate у меня есть кнопка, и я хочу использовать команду. Я не могу связать команду, потому что внутри DataTemplate datacontext не является ViewModel, а элементом ObservableCollection.

вопрос is: как привязать кнопку к команде, если потерян Родительский datacontext?

Я думаю, что это должно иметь простое решение, потому что я думаю, что это общая проблема.

представьте себе, это sceneario:

у вас есть элемент ListBox с observableCollection в качестве ItemsSource, поэтому вы используете datatemplate внутри ListBox для каждого элемента в коллекции. Ну, вы хотите удалить выбранный элемент, и вы помещаете кнопку в каждую строку для этого работа. -Как ты это делаешь?

в MVP я могу сделать это в событии click кнопки:

Button but = e.Source as Button;

if (but != null)
      Presenter.ActualNote = but.DataContext as Note;

короче. Вы отправляете DataContext строки (выбранного элемента) ведущему.

но как я могу сделать это способом mvvm? Потому что мне нужно использовать команду, но я не могу назначить команду кнопке, потому что кнопка ничего не знает о ViewModel (где команда существует).

Как вы можете видеть, кнопка должна существовать внутри datatemplate, тогда datacontext больше не является ViewModel.... Вот почему мне нужно получить доступ к родительскому DataContext для доступа к команде.

Я надеюсь, что вы поняли мою проблему лучше.

спасибо.

4 ответов


Если вы хотите грязное решение MVVM-breaking, установите тег= "{Binding} " на кнопке и обработайте событие Click. В обработчике событий вызовите команду на ViewModel.


используйте привязку ниже для команды вашей кнопки:

{Binding DataContext.CommandName, 
         RelativeSource={RelativeSource FindAncestor, 
                         AncestorType={x:Type MyUserControl}}}

это скажет ему найти ваш UserControl и использовать его DataContext.


RelativeSource работает, но я не думаю, что правильно позволять элементам управления рыскать по свойствам друг друга. Странно, что кнопка, помещенная внутри представления элемента, делает что-то с внешним источником данных, а не с связанным элементом. Возможно, вам придется пересмотреть дизайн программного кода.


Хорошо, тогда как насчет изменения класса элемента данных, чтобы он имел свойство, ссылающееся на весь вид модели?

Если ваш ItemsSource имеет тип 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;
    }
}