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


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

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

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

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

Представьте себе такую сцену:

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

В MVP я могу сделать это в случае нажатия кнопки:

Button but = e.Source as Button;

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

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

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

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

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

Спасибо.

4 30

4 ответа:

Если вы хотите получить грязное, нарушающее MVVM решение, то установите тег= " {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;
    }
}