2011-04-04 70 views
4

我正在使用mvvm模式,並且我很難弄清楚如何在ListView的ItemContainerStyle中的ContextMenu上設置DataContext。從ListView的ItemContainer中爲ContextMenu設置DataContext?

我也不明白爲什麼ListView.ContextMenu和ListView的GridView.ColumnHeaderContextMenu可以從我的視圖模型中看到屬性和命令,但ListView.ItemContainerStyle內的ContextMenu不能。

錯誤

System.Windows.Data錯誤:40:BindingExpression路徑錯誤:對 '對象' '' 貨幣 '(的HashCode = 43406546)' 未找到 'AddMenuItem' 屬性。 BindingExpression:路徑= AddMenuItem; DataItem ='Currency'(HashCode = 43406546);目標元素是'ContextMenu'(Name ='');目標屬性是 '的ItemsSource'(類型 '的IEnumerable')

查看

<!-- Removed styles for clarity. --> 
<UserControl> 

<!-- Add ElementSpy to the UserControl’s rsources --> 
<UserControl.Resources> 
    <framework:ElementSpy x:Key="spy" /> 
</UserControl.Resources> 

<ListView ItemsSource="{Binding Currency}"> 

    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="ContextMenu"> 
       <Setter.Value> 
        <!-- 'AddMenuItem' property not found on 'object' 'Currency' --> 
        <!-- ContextMenu ItemsSource="{Binding AddMenuItem}"/--> 

        <!-- Use the ElementSpy resource --> 
        <ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" /> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </ListView.ItemContainerStyle> 

    <ListView.ContextMenu> 
     <!-- Works --> 
     <ContextMenu ItemsSource="{Binding EditMenuItem}" /> 
    </ListView.ContextMenu> 

    <ListView.View> 
     <GridView> 
      <GridView.ColumnHeaderContextMenu> 
       <!-- Works --> 
       <ContextMenu ItemsSource="{Binding SortMenuItem}" /> 
      </GridView.ColumnHeaderContextMenu> 

      <GridViewColumn Header="Code" 
          DisplayMemberBinding="{Binding Path=Code}" /> 

      <GridViewColumn Header="Description" 
          DisplayMemberBinding="{Binding Path=Description}" /> 

      <GridViewColumn Header="Exchange Rate" 
          DisplayMemberBinding="{Binding Path=ExchangeRate}" /> 
     </GridView> 

    </ListView.View> 

</ListView> 
</UserControl> 

代碼後面

[Export(ViewNames.CurrencyMasterView, typeof(IMasterView))] 
[PartCreationPolicy(CreationPolicy.Shared)] 
public partial class CurrencyMasterView 
    : UserControl, IMasterView 
{ 
    public CurrencyMasterView() 
    { 
     InitializeComponent(); 
    } 

    [Import] 
    private MasterViewModel ViewModel 
    { 
     set 
     { 
      this.DataContext = value; 
     } 
    } 
} 

視圖模型

[Export(typeof(MasterViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class MasterViewModel 
    : ViewModelBase 
{ 
    [ImportingConstructor] 
    public MasterViewModel(IGeneralController generalController, IRegionManager regionManager) 
    { 
    } 

    public ObservableCollection<Currency> Currency 
    { 
     get 
     { 
      return this.currency; 
     } 

     set 
     { 
      if (this.currency != value) 
      { 
       this.currency = value; 
       this.RaisePropertyChanged(() => this.Currency); 
      } 
     } 
    } 

    public List<MenuItemMvvm> SortMenuItem 
    { 
     get 
     { 
      return this.CreateSortMenuItem(); 
     } 
    } 

    public List<MenuItemMvvm> EditMenuItem 
    { 
     get 
     { 
      return this.CreateEditMenuItem(); 
     } 
    } 

    public List<MenuItemMvvm> AddMenuItem 
    { 
     get 
     { 
      return this.CreateAddMenuItem(); 
     } 
    } 

    private List<MenuItemMvvm> CreateEditMenuItem() 
    { 
     var menu = new List<MenuItemMvvm>(); 

     menu.Add(new MenuItemMvvm("_Edit") 
     { 
      Command = this.EditCommand, 
      Icon = new Image 
      { 
       Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Edit.png")) 
      } 
     }); 

     menu.Add(new MenuItemMvvm("_Duplicate") 
     { 
      Command = this.DuplicateCommand, 
      Icon = new Image 
      { 
       Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Copy.png")) 
      } 
     }); 

     menu.Add(new MenuItemMvvm("_Delete") 
     { 
      Command = this.DeleteCommand, 
      Icon = new Image 
      { 
       Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Delete.png")) 
      } 
     }); 


     return menu; 
    } 

    // Other methods removed for clarity 
} 
+0

凱文:見http://stackoverflow.com/questions/504533和http://stackoverflow.com/questions/2306386 - 您可以通過ContextMenu.PlacementTarget綁定。 – 2011-04-04 23:19:26

回答

0

您必須在綁定中使用RelativeSource和PlacementTarget。我使用下面的xaml來添加一個contextmenu來設置datagrid列的可見性。

<DataGrid.ContextMenu> 
       <ContextMenu> 
        <MenuItem Header="Spalten ein-/ausblenden">       
         <StackPanel> 
          <ItemsControl 
          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.Columns, Mode=OneWay}" 
          ItemTemplate="{StaticResource Visibility4DataGridColumns}" 
          ></ItemsControl> 
         </StackPanel> 
        </MenuItem> 
       </ContextMenu> 
      </DataGrid.ContextMenu> 
1

凱文:

這個問題讓我看着辦吧。 WPF MenuItem.Command binding to ElementName results to System.Windows.Data Error: 4 : Cannot find source for binding with reference

我更新了有此問題的其他人的源代碼。

爲了快速參考,這是我做的。

添加Josh Smith的ElementSpy類。 Enable ElementName Bindings with ElementSpy

將ElementSpy添加到UserControl的rsources。

<UserControl.Resources> 
    <framework:ElementSpy x:Key="spy" /> 
</UserControl.Resources> 

然後綁定到資源並使用Element屬性綁定到DataContext和您選擇的屬性。

<ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" />