Подтвердить что ты не робот

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

Я просмотрел эту сеть и 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 для доступа к команде.

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

Спасибо.

4b9b3361

Ответ 1

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

Ответ 2

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

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

Это скажет, чтобы найти ваш UserControl и использовать его DataContext.

Ответ 3

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

Ответ 4

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

Если ваш 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;
    }
}