开发者

How can I attach a Command with parameter to a *new* ContextMenu item?

I've attached commands to each of my context menu items as mentioned in other threads:

<StackPanel.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles/LabelledFieldStyles.xaml" />
            <ResourceDictionary>
                <Style TargetType="{x:Type MenuItem}" x:Key="ContextMenuItemStyle">
                    <Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type PetRegistry:RegistrationPanel}},Path=DataContext.CopyCommand}" />
                    <Setter Property="CommandParameter" Value="{Binding}" />
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</StackPanel.Resources>
<Label Name="copyPetContextTarget" 
       Content="(Right-click here to copy an existing pet's details)" Width="Auto">
    <Label.ContextMenu>
        <ContextMenu Name="copyPetMenu" ItemsSource="{Binding Pets}"
                    ItemContainerStyle="{StaticResource ContextMenuItemStyle}"
                    Visibility="Visible">
            <ContextMenu.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ContextMenu.ItemTemplate>
        </ContextMenu>
    </Label.ContextMenu>
</Label>

The ItemsSource is connected to Pets, which is an ObservableCollection. When I add a new pet, "Fluffy", it shows up in the list of context menu items. However, there's no command attached - selecting merely closes the menu without triggering the command.

Strangely, using a list instead of an ObservableCollection and notifying the relevant property change doesn't even cause the new pet to show up in the menu.

How can I make a new pet bind to the command when it's added? Or is this just a strange bug?

Edit: It's working fine for existing pets. The binding isn't necessarily the problem - it's only not attaching when a new pet is added to the list. I'm sure code-behind will work - I'm thinking that maybe there's some property I need to notify about, or some way of binding the command differently. Otherwise I'm just going to write some code-behind.

Edit2: Interesting! There's actually an error being output (silently as is the way with WPF) - it can't find the binding. Is there a different way of getting hold of that parent data context which might be simple开发者_开发百科r?

Edit3: @Yurec nailed it, but while this works manually, it fails for Microsoft UI Automation. Doh! So I've created a CopiablePet object which has the CopyCommand embedded in it. Ugly, but it works. Will file a bug report with Microsoft if I get round to it as this is very silly.


Possible reason for such behaviour is because menu items are not in the same visual tree as PetRegistry:RegistrationPanel. Please try to replace Command binding to something like this

<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}},Path=PlacementTarget.DataContext.CopyCommand}" />

Of course Label should contain the same DataContext as PetRegistry:RegistrationPanel.


I used in one of mine project something like this and it works for me:

<Style x:Key="FrameSubmenuItem" TargetType="MenuItem">
.....
....
    <Setter Property="Command" Value="NavigationCommands.NavigateJournal"/>
    <Setter Property="CommandTarget"
            Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Menu}},
                            Path=TemplatedParent}"/>
    <Setter Property="CommandParameter"
            Value="{Binding RelativeSource={RelativeSource Self}}"/>
.....

...

Look on CommandTarget use.

EDIT

Check the command binding by applying a Converter, at least for test reason, cause most likely, the binding of the command for new menu items somehow fails.

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜