2015-02-24 4 views
-1

Я изо всех сил пытаюсь понять, где я ошибаюсь в проекте MVVM WPF. Я пытаюсь создать пользовательскую команду contextmenu. У меня есть рабочее пространство, которое является представлением, внутри HCC в моем MainWindow. Рабочая область (ProductRecordView) содержит список, заполненный наблюдаемой коллекцией с помощью viewmodel (ProductRecordViewModel). Контекст данных задается Option 8, в MainWindowResources XAML. Таким образом, я создал Контекстное в PRV следующим образом:Связывание контекстного меню в проекте MVVM WPF

<ListView.ContextMenu> 
    <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
    <MenuItem Header="Delete" Command="{Binding Path=DeleteRecord}"/> 
    </ContextMenu> 
</ListView.ContextMenu> 

и в PRVM у меня есть следующие вещи:

#region Presentation Properties 

public ICommand DeleteRecord 
{ 
    get 
    { 
     if (_deleteMe == null) 
     { 
      _deleteMe = new RelayCommand(
       param => this.Delete(), 
       param => this.CanDelete 
       ); 
     } 

     return _deleteMe; 
    } 
} 

#endregion Presentation Properties 

#region Public Methods 

public void Delete() 
{ 
    MessageBox.Show("Test Execute");//this is just for testing the binding of Delete 
} 

#endregion Public Methods 

#region Private Helpers 

bool CanDelete = false; //this is just for testing the binding of CanDelete 

#endregion Private Helpers 

При запуске приложения и щелкните правой кнопкой мыши на элемент в списке view, мне представлено контекстное меню, как описано в первом фрагменте, однако оно не является обязательным, как предполагалось, поскольку ни один из связанных результатов не возникает. Как я правильно связываю в этом случае, что я делаю неправильно?

DataContext из ProductRecordView устанавливается в MainWindowResources следующим образом:

<DataTemplate DataType="{x:Type vm:ProductRecordViewModel}"> 
    <vw:ProductRecordView /> 
</DataTemplate> 

Я знаю, что это DataContext работает как задумано, как будто я пытаюсь создать кнопку в окне и назначить привязки данных к нему, связывание прекрасно работает и выполняет команду в ProductRecordViewModel

+0

Проверьте окно вывода, вероятно, вы имеете ошибку привязки. Можете ли вы предоставить это? Кроме того, использование RelativeSource Self не выглядит правильным, уверены, что вы привязываетесь к правильному элементу? –

+0

@MikeEason Да, я должен был, наверное, сказать в моем вопросе; вот ошибка: Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression: свойство 'DeleteRecord' не найдено в 'object' '' ListCollectionView '(HashCode = 12713695)'. BindingExpression: Path = DeleteRecord; DataItem = 'ListCollectionView' (HashCode = 12713695); целевым элементом является «MenuItem» (Name = ''); target свойство - «Command» (тип «ICommand»), но я понятия не имею, что это значит или как его исправить :( –

+0

определить x: имя на вашем представлении и в MenuItem write puko

ответ

1

Давайте посмотрим на сообщение об ошибке более точно.

BindingExpression path error: 'DeleteRecord' property not found on 'object' ''ListCollectionView' (HashCode=12713695)'. BindingExpression:Path=DeleteRecord; DataItem='ListCollectionView' (HashCode=12713695); target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')

Это утверждает, что система привязки данных пытается найти DeleteRecord недвижимость в MenuItem «s DataContext который имеет тип ListCollectionView.

Таким образом, учитывая ваше выражение

DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}} 

ясно, что PlacementTarget.DataContext имеет тип ListCollectionView тоже. Так как PlacementTarget - это ListView, очевидно, что ListViewDataContext - это ListCollectionView объект.

Я полагаю, вы определяете ваши ListView «ы DataContext как-то вроде этого:

<ListView DataContext="{Binding Items}" ItemsSource="{Binding}"/> 

Лучшим решением было бы оставить ListView» s DataContext в одиночку, так что он „наследует“ это значение из вашего UserControl (Таким образом, будет иметь тип ProductRecordViewModel) при изменении привязки для ItemsSource:

<ListView ItemsSource="{Binding Items}"/> 
0

Почему в ProductRecordView в DataTemplate? Я получаю подозрение, что элементы списка PRV, каждый из которых связан с PRVM, - это правильно? Что-то вроде этого

<ListView> 
    <ListView.ContextMenu> 
      <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
       <MenuItem Header="Delete" Command="{Binding Path=DeleteRecord}"/> 
      </ContextMenu> 
     </ListView.ContextMenu> 
    <ListView.ItemTemplate> 
     <DataTemplate DataType="{x:Type vm:ProductRecordViewModel}"> 
      <vw:ProductRecordView /> <!-- each PRV is bound to a PRVM - which as the delete record command --> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Если это так, то проблема заключается в том, что DataContext из listviewitems не то же самое, как и сам ListView.Вместо этого вы, вероятно, хотите прямое контекстное меню в listviewitems:

<ListView>   
     <ListView.ItemTemplate> 
      <DataTemplate DataType="{x:Type vm:ProductRecordViewModel}"> 
       <vw:ProductRecordView> 
        <vw:ProductRecordView.ContextMenu> 
         <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
          <MenuItem Header="Delete" Command="{Binding Path=DeleteRecord}"/> 
         </ContextMenu> 
        <vw:ProductRecordView.ContextMenu> 
       </vw:vw:ProductRecordView> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
Смежные вопросы