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

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

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

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

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

Представьте себе этот сценарий:

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

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

Button but = e.Source as Button;

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

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

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

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

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

Спасибо.

Ответы [ 4 ]

89 голосов
/ 16 июня 2009

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

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

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

5 голосов
/ 16 июня 2009

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

3 голосов
/ 17 июня 2009

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

Если ваш 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;
    }
}
2 голосов
/ 16 июня 2009

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

...