P.Dijk
P.Dijk

Reputation: 55

C# wpf Databinding command not working in contextmenu

I am learning wpf and mvvm and I decided to create a Soundboard for myself to practice and so far it's going pretty well. Now I have made a datatemplate where for every file that the program finds in the specified directory it will create a button with the name of the file in it and I can click it to play. So far so good. However I now tried to make a ContextMenu so that when I want to remove a file from the list I can right click and select remove, but this command doesn't work even though I have the exact same command structure for the regular button.

I am really quite confused with the whole RelativeSource thing and was already happy my regular 'play' command worked in the button.

If someone could point me in the right direction that would be great. I really could use an explanation on my specific problem as that always seems to help me more then a generic example somehow. I have tried to read on all the related questions but just don't seem to figure it out from there.

My ItemsControl:

<ItemsControl x:Name="MySounds" ItemsSource="{Binding Sounds}">

ItemTemplate:

<ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button Style="{StaticResource mainButton}"
                                Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
                                CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
                                Tag="{Binding Path=Name}">
                            <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
                            <Button.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="{Binding Path=Name}" 
                                              Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.RemoveSound}" 
                                              CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}">
                                        <MenuItem.Icon>
                                            <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
                                        </MenuItem.Icon>
                                    </MenuItem>
                                </ContextMenu>
                            </Button.ContextMenu>
                        </Button>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

I have a generic RelayCommand in my viewmodel and that all works, the problem really is just with the binding.

Upvotes: 3

Views: 1481

Answers (2)

mm8
mm8

Reputation: 169160

If you bind the Tag property of the Button to the ItemsControl, you could bind to the command using the PlacementTarget property of the ContextMenu:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <StackPanel>
            <Button Style="{StaticResource mainButton}"
                                Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
                                CommandParameter="{Binding Path=Name}"
                                Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}">
                <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="{Binding Path=Name}" 
                                  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveSound}" 
                                  CommandParameter="{Binding Path=Name}">
                            <MenuItem.Icon>
                                <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
        </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>

Upvotes: 2

Kalyh
Kalyh

Reputation: 63

You can try to replace your command string in your MenuItem by this :

Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.RemoveSound}"

Upvotes: 0

Related Questions