web-dev-qa-db-fra.com

Passer le paramètre de commande à partir du xaml

J'essaie de faire quelque chose comme ça:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding RemoveRow}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

mais je suis toujours nul (j'ai aussi essayé SelectedIndex et SelectedValue)

si je passe le paramètre suivant au code d'exécution, cela fonctionne:

<MenuItem Command="{Binding RemoveRow}" CommandParameter="1">
21
Maya

Essayez quelque chose comme ça dans votre CommandParameter,

<DataGrid.ContextMenu>
     <ContextMenu>
           <MenuItem Header="MyHeader" 
                     Command="{Binding MyCommand}"
                     CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItem}" />
</DataGrid.ContextMenu>

Je l'ai déjà testé et ça devrait marcher.

22
Rayan Elmakki

Cela ne fonctionne pas car le ContextMenu ne fait pas partie de l'arborescence visuelle ou logique du DataGrid, il n'hérite donc pas du DataContext.

Pour autant que je sache, il existe une solution simple à ce problème en utilisant uniquement le système de reliure intégré. Cependant, en utilisant une simple classe "proxy" comme expliqué ici , vous pouvez contourner ce problème:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.Resources>
       <local:BindingProxy x:Key="proxy" Data="{Binding}" />
   </DataGrid.Resources>
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding Data.RemoveRow, Source={StaticResource proxy}}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

Cependant, vous avez toujours un problème: ElementName=myGrid ne fonctionne pas (encore une fois, parce que ContextMenu n'est pas dans l'arborescence visuelle ou logique de DataGrid, il n'est donc pas dans la portée du même nom). Une solution simple consiste à lier le SelectedItem du DataGrid à une propriété du ViewModel et à utiliser cette propriété au lieu du paramètre de commande:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}"
          SelectedItem="{Binding SelectedItem}">
   <DataGrid.Resources>
       <local:BindingProxy x:Key="proxy" Data="{Binding}" />
   </DataGrid.Resources>
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding Data.RemoveRow, Source={StaticResource proxy}}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>
18
Thomas Levesque