0
votes

I have a problem. I am trying to create a context menu with databinding in wpf. The context menu items would are bound to an observable collection of objects. The population of context menu is fine - however, I want to add the command to it.

The way I am using it is:

in XAML

 <Grid.Resources>
            <local:RestoreCommand x:Key="RestoreCommand" />
            <local:ShowBalloonCommand x:Key="BaloonCommand" />
            <local:StartTaskCommand x:Key="StartTaskCommand" />
        </Grid.Resources>

<ContextMenu ItemsSource="{Binding}" Name="taskBarContextMenu">
                    <ContextMenu.ItemContainerStyle>
                        <Style TargetType="MenuItem">
                            <Setter Property="Command" Value="{StaticResource StartTaskCommand}"/>
                            <Setter Property="CommandParameter" Value="{Binding mainWindow}"/>
                        </Style>
                    </ContextMenu.ItemContainerStyle>

and

<TextBlock TextWrapping="Wrap" Text="{Binding Name}" Grid.Column="0"/>
                                    <TextBlock TextWrapping="Wrap" Text="{Binding TimeElapsed, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2"/>

and in C#:

taskbarIcon.ContextMenu.ItemsSource = TasksList;

And I have a class for the command

public class StartTaskCommand : ICommand
    {
        public void Execute(object parameter)
        {
            //THE PARAMETER IS ALWAYS NULL
            var window = parameter as MainWindow;
            if (window != null)
            {

            }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;
    } 

I have it set up simiarly for other two commands and it works fine. Anything I try to add as the parameter is always null - be it taskBarContextMenu, or mainWindow or menuItem... Any ideas welcome.

====

I tried a following solution as suggested, but the command parameter is still null:

 <tb:TaskbarIcon Name="taskbarIcon"
            DoubleClickCommand="{StaticResource RestoreCommand}"
            DoubleClickCommandParameter="{Binding ElementName=mainWindow}"

            LeftClickCommand="{StaticResource BaloonCommand}"
            LeftClickCommandParameter="{Binding ElementName=mainWindow}"
            IconSource=".\256px-Out_of_date_clock_icon.ico"
                        MenuActivation="RightClick"
                        Tag="{Binding ElementName=mainWindow}"
                        >



<tb:TaskbarIcon.ContextMenu ><ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" Tag="{Binding}" Name="taskBarContextMenu">
            <ContextMenu.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="Command" Value="{StaticResource StartTaskCommand}"/>
                    <Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}"/>
                </Style>
            </ContextMenu.ItemContainerStyle>
1

1 Answers

0
votes

You need to add a tag to the menu's container and bind to it using placement target.

View this example:

<StackPanel x:Key="ConfigurationListItem" x:Shared="False" Tag="{Binding ElementName=UserControl}">
        <StackPanel Orientation="Horizontal">
            <Button>
                <Button.InputBindings>
                    <MouseBinding Gesture="LeftDoubleClick" Command="{Binding ElementName=UserControl, Path=LaunchCommand}" CommandParameter="{Binding}" />
                    <MouseBinding Gesture="LeftClick" Command="{Binding ElementName=UserControl, Path=SelectCommand}" CommandParameter="{Binding}" />
                </Button.InputBindings>
        </StackPanel>

        <StackPanel.ContextMenu>
            <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" Tag="{Binding}">
                <MenuItem Header="Sync Environment Dependencies" 
                        Command="{Binding Parent.PlacementTarget.Tag.SyncEnvironmentCommand, RelativeSource={RelativeSource Self}}"
                        CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}" />
            </ContextMenu>
        </StackPanel.ContextMenu>
    </StackPanel>