2010-10-01 136 views
3

我知道這個問題在很多網站和StackOverFlow中都以不同的方式被問過很多次,但是我發現的所有答案都沒有幫助我確切地說我無法理解他們並在我的應用程序中執行。所以我想從我的應用程序中添加一些代碼,以便人們可以更好地幫助我。上下文菜單項命令綁定使用MVVM的WPF

問題陳述:我正在使用WPF DataGrid。我添加了一個上下文菜單,我有3個選項剪切,複製,粘貼。我正在使用MVVM進行開發。我想DataBind這些選項到我的ViewModel中的命令。但我無法這樣做。上下文菜單選項沒有獲取數據綁定!

這是我的併網標準的XAML:

<custom:DataGrid 
     x:Name="DataGrid_Standard" 
     Grid.Row="1" Grid.Column="1" 
     AutoGenerateColumns="False"               
     IsSynchronizedWithCurrentItem="True" 
     Background="Transparent" 
     ItemsSource="{Binding FullGridData}" 
     ItemContainerStyle="{StaticResource defaultRowStyle}" 
     ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"       
     Grid.ColumnSpan="2"> 

然後,我有一個ContextMenu和頭元素

<ContextMenu x:Key="columnHeaderMenu"> 
    <MenuItem Command="{Binding CutCommand}" 
      Header="Test" /> 
    <MenuItem Header="Copy"/> 
    <MenuItem Header="Paste"/> 
</ContextMenu> 
<Style TargetType="{x:Type custom:DataGridColumnHeader}" x:Key="DefaultColumnHeaderStyle"> 
    <Setter Property="ContextMenu" Value="{DynamicResource columnHeaderMenu}" > 
</Style> 

一個樣式該行雲在我的構造

public Window1() 
{    
    this.DataContext = new AppData(); 
} 

此代碼進入我的AppData類:

public class AppData 
{ 
    private IList<GridData> fullGridData = new ObservableCollection<GridData>();<br> 
    public IList<GridData> FullGridData 
    { 
     get { return fullGridData; } 
     set { fullGridData = value; } 
    } 

    private DelegateCommand<object> cutCommand; 
    public DelegateCommand<object> CutCommand 
    { 
     get 
     { 
      if (cutCommand == null) 
      { 
       cutCommand = new DelegateCommand<object>(CutColumn); 
      } 
      return cutCommand; 
     } 
    } 

    private void CutColumn(object obj) 
    { 
     //some code goes here 
    } 
} 

**我想確切地知道我在哪裏做錯了?爲什麼DataBinding不會發生? 請幫我解決這個問題。請向我提供示例代碼或修改我現在可以實現的代碼。 **

回答

-1

您有兩種選擇。
注意:我在這裏添加的代碼示例與您的示例類似,但不相同。

移動文本菜單的定義DataGrid中確定指標裏面如下:

<WpfToolkit:DataGrid 
    x:Name="DataGrid_Standard" 
    IsSynchronizedWithCurrentItem="True" 
    Background="Transparent" 
    ItemsSource="{Binding FullGridData}" 
    ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"> 
    <WpfToolkit:DataGrid.ContextMenu> 
     <ContextMenu> 
      <MenuItem Command="{Binding CutCommand}" Header="Test" /> 
      <MenuItem Header="Copy"/> 
      <MenuItem Header="Paste"/> 
     </ContextMenu> 
    </WpfToolkit:DataGrid.ContextMenu> 
</WpfToolkit:DataGrid> 

或更好的CommandReference添加到您的資源,並設置命令在菜單項的靜態資源如下:

<Window.Resources> 
    <c:CommandReference x:Key="MyCutCommandReference" Command="{Binding CutCommand}" /> 

    <ContextMenu x:Key="columnHeaderMenu"> 
     <MenuItem Command="{StaticResource MyCutCommandReference}" Header="Test" /> 
     <MenuItem Header="Copy"/> 
     <MenuItem Header="Paste"/> 
    </ContextMenu> 

    <Style TargetType="{x:Type Primitives:DataGridColumnHeader}" x:Key="DefaultColumnHeaderStyle"> 
     <Setter Property="ContextMenu" Value="{DynamicResource columnHeaderMenu}" /> 
    </Style> 

</Window.Resources> 

<WpfToolkit:DataGrid 
    x:Name="DataGrid_Standard" 
    IsSynchronizedWithCurrentItem="True" 
    Background="Transparent" 
    ItemsSource="{Binding FullGridData}" 
    ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"/> 
+1

,因爲我想只爲header.Actually上下文菜單我現在用你的第二個解決方案命令正在關聯,但我的菜單項被禁用。我正在使用DelegateCommand類進行綁定。它真的很奇怪爲什麼我的菜單項被禁用? – GuruC 2010-10-04 07:20:16

+0

它爲我工作,但我不知道你使用的是什麼DelegateCommand的實現;看看控制命令是否啓用的第二個參數。我在這裏添加了一個示例: cutCommand = new DelegateCommand (CutColumn,CanCutCommand); private bool CanCutCommand(object obj) { return true; } – Zamboni 2010-10-04 15:20:47

+0

我使用codeplex的mvvm工具包中提供的DelegateCommand。我看過一些他們說錯誤的網站。鏈接如下所示:http://connect.microsoft.com/VisualStudio/feedback/details/421816/wpf-command-based-context-menu-item-initially-disabled http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7bd75a7c-eab4-4f3a-967b-94a9534a7455 – GuruC 2010-10-06 08:24:44

0

我有同樣的問題。一旦我將它們從後面的代碼移動到ViewModel,命令綁定停止工作。在視圖模型中,我必須將ICommand從RoutedCommand更改爲DelegateCommand。我能得到它以下列方式工作 -

添加打開事件處理程序到您的上下文菜單 -

<ContextMenu x:Key="columnHeaderMenu" Opened="ContextMenu_Opened"> 
    <MenuItem Command="{Binding CutCommand}" Header="Test" /> 
    <MenuItem Header="Copy"/> 
    <MenuItem Header="Paste"/> 
</ContextMenu> 

在後面的代碼,你將你的視圖模型分配到上下文菜單的DataContext的 -

private void ContextMenu_Opened(object sender, RoutedEventArgs e) 
{ 
    ContextMenu menu = sender as ContextMenu; 
    menu.DataContext = _vm; 
} 
0

我通常我的實例化視圖模型作爲靜態資源在我看來:

<UserControl x:Class="My.Namespace.MySampleView" ...> 
    <UserControl.Resources> 
     <viewModels:MySampleViewModel x:Key="ViewModel" /> 
    </UserControl.Resources> 

然後你就可以輕鬆地引用您的視圖模型的任何屬性,即使當前綁定上下文不是視圖模型:

<ContextMenu x:Key="columnHeaderMenu"> 
    <MenuItem Command="{Binding MyCommand, Source={StaticResource ViewModel}}" /> 
</ContextMenu> 

欲瞭解更多信息,看看我的文章Recommendations and best practices for implementing MVVM and XAML/.NET applications

0
<MenuItem Header="Cut" Command="{Binding Path=PlacementTarget.DataContext.CutCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" /> 
1

您的代碼中的某些內容(或在當時使用的WPF版本(?))過於複雜。我能夠結合如

<DataGrid AutoGenerateColumns="True" 
     Name="myGrid" 
     ItemsSource="{Binding Orders}"> 
    <DataGrid.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Copy" Command="{Binding CopyItem}" /> 
      <MenuItem Header="Delete" Command="{Binding DeleteItem}" /> 
     </ContextMenu> 
    </DataGrid.ContextMenu> 
</DataGrid> 

其中該命令是設置這樣的:

VM.DeleteItem 
    = new OperationCommand((o) => MessageBox.Show("Delete Me"), 
          (o) => (myGrid.SelectedItem as Order)?.InProgress == false); 

enter image description here