简体   繁体   中英

Share context menu in WP7 xaml

I want to add a contextmenu to items in a listbox. Typically the answer is to add the contextmenu to the root of the item template. However, I am using a template selector, so there are multiple templates in use, depending on the data of each item in the listbox. This means I need to add the same contextmenu definition to each template, which is not very appealing.

One solution is to wrap the datatemplate in a ContentControl, which would give me a single place for the context menu definition. However, I believe this would add layout overhead that isn't necessary.

Another solution I tried is adding the ContextMenu to the resource dictionary, but I believe this ends up sharing the same object instance across all the uses, and due to the way ContextMenu is implemented, this also does not work.

A third solution is using the Loaded event to call a function which populates the context menu appropriately. However, this ends up moving a lot of code that ought to be in the XAML into code, and looks quite ugly. If there's some way of defining the context menu in xaml, and then just referencing that from code, I would find it appealing, but I don't quite see how to do that.

What is the right way to share the same ContextMenu across the templates in a template selector?


This is the ContentControl method, which works, but ends up adding two content controls to each item:

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ContentControl>
                        <toolkit:ContextMenuService.ContextMenu>
                            <toolkit:ContextMenu Loaded="ContextMenu_Loaded">
                                <toolkit:MenuItem Header="Delete"/>
                            </toolkit:ContextMenu>
                        </toolkit:ContextMenuService.ContextMenu>
                        <ContentControl ContentTemplate="{StaticResource MyTemplate}" Content="{Binding}"/>
                    </ContentControl>
                </DataTemplate>
            </ListBox.ItemTemplate>

How about adding the ContextMenu to the TemplateSelector?

<ListBox ItemsSource="{Binding}">
    <ListBox.Resources>
        <DataTemplate x:Key="MyTemplate">
            <StackPanel>
                <TextBlock Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:CustomTemplateSelector Content="{Binding}">
                <toolkit:ContextMenuService.ContextMenu>
                    <toolkit:ContextMenu>
                        <toolkit:MenuItem Header="Delete"
                                            Click="MenuItem_Click" />
                    </toolkit:ContextMenu>
                </toolkit:ContextMenuService.ContextMenu>
                <local:CustomTemplateSelector.TemplateOne>
                    <DataTemplate>
                        <ContentControl Content="{Binding}"
                                        ContentTemplate="{StaticResource MyTemplate}"
                                        Foreground="Blue" />
                    </DataTemplate>
                </local:CustomTemplateSelector.TemplateOne>
                <local:CustomTemplateSelector.TemplateTwo>
                    <DataTemplate>
                        <ContentControl Content="{Binding}"
                                        ContentTemplate="{StaticResource MyTemplate}"
                                        Foreground="Red" />
                    </DataTemplate>
                </local:CustomTemplateSelector.TemplateTwo>
                <local:CustomTemplateSelector.TemplateThree>
                    <DataTemplate>
                        <ContentControl Content="{Binding}"
                                        ContentTemplate="{StaticResource MyTemplate}"
                                        Foreground="Yellow" />
                    </DataTemplate>
                </local:CustomTemplateSelector.TemplateThree>
            </local:CustomTemplateSelector>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I ran this and it worked for me - give it a try and let me know if this was the effect you were looking for or not.

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