简体   繁体   中英

Bind CommandParameter from ContextMenu in DataTemplate and ItemsControl

In my viewmodel, I have an ObservableCollection which holds elements of the type VaultViewModel . My view binds to this collection using an ItemsControl . Because I also want to display one additional item of the type NewVault , I implemented it like this:

<ItemsControl.Resources>
    <CollectionViewSource x:Key="VaultsCollection" Source="{Binding VaultViewModels}"/>
    <DataTemplate DataType="{x:Type viewmodels:VaultViewModel>
        ... data template for my vaults
    </DataTemplate>
    <DataTemplate DataType="{x:Type models:NewVault>
        ... data template for the additional item
    </DataTemplate>
</ItemsControl.Resources>

<ItemsControl.ItemsSource>
    <CompositeCollection>
        <CollectionContainer Collection="{Binding Source={StaticResource VaultsCollection}}"/>
        <models:NewVault/>
    </CompositeCollection>
</ItemsControl.ItemsSource>

In my DataTemplate for the elements of the type VaultViewModel , I have a Canvas which displays a ContextMenu when left-clicking on it:

<Canvas ...>
    <Canvas.Style>
        <Style TargetType="Canvas">
            <Style.Triggers>
                <EventTrigger RoutedEvent="MouseLeftButtonUp">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>                    
                                <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">                                                                       
                                    <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Edit..."/>
                        <MenuItem Header="Delete" 
                                  Command="{Binding Source={x:Reference Name=icMain}, Path=DataContext.DeleteVaultCommand}"
                                  CommandParameter="{Binding}"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </Canvas.Style>
</Canvas>

In my MenuItem I am binding to a command which is implemented in my viewmodel. The command is being executed but I have problems binding the CommandParameter .

I want to pass the current element of the ItemsControl which is a VaultViewModel using CommandParameter="{Binding}" , but the parameter of the command is null and there is no error in the console. My question is how I pass the current element of the ItemsControl as the CommandParameter .

I made it work by implementing a proxy in the resources of the Canvas which holds the DataContext . After that, I can use the proxy as a StaticResource for the CommandParameter :

<Canvas.Resources>
    <DiscreteObjectKeyFrame x:Key="DataContextProxy" Value="{Binding}"/>
</Canvas.Resources>

<MenuItem ... CommandParameter="{Binding Source={StaticResource DataContextProxy}}"/>

The parameter will be of type System.Windows.Media.Animation.DiscreteObjectKeyFrame which holds the DataContext in its property Value .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM