【问题标题】:Can you add items to a context menu in a parents menu?您可以将项目添加到父菜单中的上下文菜单吗?
【发布时间】:2010-05-26 04:26:24
【问题描述】:

或者相反,您可以将父菜单项导入子窗口吗?

所以我有一个由控件组成的 UI,这些控件都有自己的上下文菜单,但我们也有一个嵌套在我们的通用容器中的数据网格。

因此,当您右键单击数据网格元素时,我想同时显示我为数据网格创建的上下文项和通用容器中的项。

【问题讨论】:

    标签: c# .net wpf xaml


    【解决方案1】:

    这是一个使用一些附加属性手动将多个 ContextMenus 组合在一起的解决方案。

    注意:由于它使用 XAMLReader 来克隆 MenuItem,因此此解决方案不会在继承的 MenuItem 中保留绑定。

    using System.IO;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
    using System.Xml;
    
    namespace ContextMenuSample
    {
        public static class InheritMenu
        {
            public static readonly DependencyProperty ContextMenuProperty = DependencyProperty.RegisterAttached(
                "ContextMenu", typeof(ContextMenu), typeof(InheritMenu), new FrameworkPropertyMetadata(null, OnContextMenuChanged));
            private static void OnContextMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                SetContextMenu(d as FrameworkElement);
            }
            public static void SetContextMenu(FrameworkElement element, ContextMenu value)
            {
                element.SetValue(ContextMenuProperty, value);
            }
            public static ContextMenu GetContextMenu(FrameworkElement element)
            {
                return (ContextMenu)element.GetValue(ContextMenuProperty);
            }
    
            public static readonly DependencyProperty ParentMenuProperty = DependencyProperty.RegisterAttached(
                "ParentMenu", typeof(ContextMenu), typeof(InheritMenu), new FrameworkPropertyMetadata(null, OnParentMenuChanged));
            private static void OnParentMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                SetContextMenu(d as FrameworkElement);
            }
            public static void SetParentMenu(FrameworkElement element, ContextMenu value)
            {
                element.SetValue(ParentMenuProperty, value);
            }
            public static ContextMenu GetParentMenu(FrameworkElement element)
            {
                return (ContextMenu)element.GetValue(ParentMenuProperty);
            }
    
            private static void SetContextMenu(FrameworkElement element)
            {
                var context = GetContextMenu(element);
                var parent = GetParentMenu(element);
                if (context == null || parent == null) return;
                var menu = new ContextMenu();
                foreach (var item in parent.Items)
                    menu.Items.Add(SimpleXamlClone(item));
                menu.Items.Add(new Separator());
                foreach (var item in context.Items)
                    menu.Items.Add(SimpleXamlClone(item));
                element.ContextMenu = menu;
            }
    
            public static object SimpleXamlClone(object original)
            {
                var xaml = XamlWriter.Save(original);
                var reader = new StringReader(xaml);
                var xml = XmlReader.Create(reader);
                return XamlReader.Load(xml);
            }
        }
    }
    

    <Window x:Class="ContextMenuSample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:ContextMenuSample"
        Title="Window1" Height="250" Width="500">
        <Window.Resources>
            <l:MyCommand x:Key="MainCommand" Message="Main Command!" />
            <l:MyCommand x:Key="ScopeACommand" Message="Scope A Command!" />
            <l:MyCommand x:Key="ScopeBCommand" Message="Scope B Command!" />
            <l:MyCommand x:Key="ScopeCCommand" Message="Scope C Command!" />
            <l:MyCommand x:Key="ScopeDCommand" Message="Scope D Command!" />
            <Style TargetType="Label">
                <Setter Property="HorizontalAlignment" Value="Center" />
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="HorizontalAlignment" Value="Center" />
            </Style>
        </Window.Resources>
        <!-- Main Scope -->
        <Grid Margin="8" Background="LightGray">
            <Grid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Main Scope" Command="{StaticResource MainCommand}" />
                </ContextMenu>
            </Grid.ContextMenu>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Label Grid.ColumnSpan="2" Grid.Row="0">Main Scope</Label>
            <Label Grid.ColumnSpan="2" Grid.Row="1">Check ContextMenu Here!</Label>
    
            <!-- Scope A -->
            <StackPanel Grid.Column="0" Grid.Row="2" Margin="8" Background="LightBlue">
                <l:InheritMenu.ParentMenu>
                    <Binding Path="ContextMenu" RelativeSource="{RelativeSource AncestorType={x:Type Grid}}" />
                </l:InheritMenu.ParentMenu>
                <l:InheritMenu.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Scope A" Command="{StaticResource ScopeACommand}" />
                    </ContextMenu>
                </l:InheritMenu.ContextMenu>
                <Label>Scope A</Label>
                <Label>Check ContextMenu Here!</Label>
    
                <!-- Scope C -->
                <StackPanel Margin="8" Background="LightGreen">
                    <l:InheritMenu.ParentMenu>
                        <Binding Path="ContextMenu" RelativeSource="{RelativeSource AncestorType={x:Type StackPanel}}" />
                    </l:InheritMenu.ParentMenu>
                    <l:InheritMenu.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Scope C" Command="{StaticResource ScopeCCommand}" />
                        </ContextMenu>
                    </l:InheritMenu.ContextMenu>
                    <Label>Scope C</Label>
                    <Label>Check ContextMenu Here!</Label>
                </StackPanel>
            </StackPanel>
    
            <!-- Scope B -->
            <StackPanel Grid.Column="1" Grid.Row="2" Margin="8" Background="LightCoral">
                <l:InheritMenu.ParentMenu>
                    <Binding Path="ContextMenu" RelativeSource="{RelativeSource AncestorType={x:Type Grid}}" />
                </l:InheritMenu.ParentMenu>
                <l:InheritMenu.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Scope B" Command="{StaticResource ScopeBCommand}" />
                    </ContextMenu>
                </l:InheritMenu.ContextMenu>
                <Label>Scope B</Label>
                <Label>Check ContextMenu Here!</Label>
    
                <!-- Scope D -->
                <StackPanel Margin="8" Background="LightSalmon">
                    <l:InheritMenu.ParentMenu>
                        <Binding Path="ContextMenu" RelativeSource="{RelativeSource AncestorType={x:Type StackPanel}}" />
                    </l:InheritMenu.ParentMenu>
                    <l:InheritMenu.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Scope D" Command="{StaticResource ScopeDCommand}" />
                        </ContextMenu>
                    </l:InheritMenu.ContextMenu>
                    <Label>Scope D</Label>
                    <Label>Check ContextMenu Here!</Label>
                </StackPanel>
            </StackPanel>
        </Grid>
    </Window>
    

    public class MyCommand : ICommand
    {
        public string Message { get; set; }
        public void Execute(object parameter) { MessageBox.Show(Message); }
        public bool CanExecute(object parameter) { return true; }
        public event EventHandler CanExecuteChanged;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 2014-06-03
      • 2010-10-08
      相关资源
      最近更新 更多