tan
站在牛顿头上吃苹果的程序员

   Silverlight 4新增了右键菜单功能,通过contextMenu控件来实现右击菜单的功能.简单的右键菜单功能非常容易实现,网上很多朋友都有提供示例分享,最近因为项目需要得实现多级右键菜单功能,效果如下:

  

  实现参照了网络上的几个实现方式,现将代码贴出,希望对大家有所帮助。

MenuItemDemo.xaml

View Code
 1 <UserControl x:Class="Demo.MenuItemDemo"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable="d"
7 d:DesignHeight="300" d:DesignWidth="400">
8
9 <Grid x:Name="LayoutRoot" Background="White" MouseRightButtonDown="LayoutRoot_MouseRightButtonDown" MouseRightButtonUp="LayoutRoot_MouseRightButtonUp">
10
11 </Grid>
12 </UserControl>

MenuItemDemo.xaml.cs

View Code
 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12
13 namespace Demo
14 {
15 public partial class MenuItemDemo : UserControl
16 {
17 public MenuItemDemo()
18 {
19 InitializeComponent();
20 CreateMark();
21 }
22 ContextMenu menu = new ContextMenu();
23
24
25 private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
26 {
27 e.Handled = true;
28 menu.IsOpen = true;//显示菜单
29 }
30
31 ///<summary>
32 /// 创建菜单
33 ///</summary>
34 private void CreateMark()
35 {
36 string[] menuitem = { "菜单项1", "菜单项2", "菜单项3" };
37 SuperMenuItem itemone = new SuperMenuItem()
38 {
39 Header = "请选择菜单项:",
40 Background = new SolidColorBrush(Colors.Green),
41 Foreground = new SolidColorBrush(Colors.White)
42 };
43 SuperMenuItem itemtwo = new SuperMenuItem() { Header = "菜单1" };
44 SuperMenuItem itemthree = new SuperMenuItem() { Header = "菜单2" };
45 //设置显示方向
46 //itemtwo.FlowDirection = System.Windows.FlowDirection.RightToLeft;
47 foreach (var item in menuitem)
48 {
49 MenuItem items = new MenuItem { Header = item };
50 //事件
51 items.MouseLeftButtonUp += new MouseButtonEventHandler(items_MouseLeftButtonUp);
52 itemtwo.Items.Add(items);
53 }
54
55
56
57 menu.Items.Add(itemone);
58 menu.Items.Add(itemtwo);
59 menu.Items.Add(itemthree);
60
61 }
62
63 void items_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
64 {
65 menu.IsOpen = false;//隐藏菜单
66 }
67
68 private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
69 {
70 e.Handled = true;
71 }
72 }
73 }

 

app.xaml

  

View Code
 1  <Style TargetType="local:SuperMenuItem">
2 <Setter Property="Background" Value="Transparent"/>
3 <Setter Property="BorderBrush" Value="Transparent"/>
4 <Setter Property="Padding" Value="4,3,2,3"/>
5 <Setter Property="Template">
6 <Setter.Value>
7 <ControlTemplate TargetType="local:SuperMenuItem">
8 <Grid>
9 <VisualStateManager.VisualStateGroups>
10 <VisualStateGroup x:Name="CommonStates">
11 <VisualState x:Name="Normal"/>
12 <VisualState x:Name="Disabled">
13 <Storyboard>
14 <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Presenter"/>
15 </Storyboard>
16 </VisualState>
17 </VisualStateGroup>
18 <VisualStateGroup x:Name="FocusStates">
19 <VisualState x:Name="Unfocused"/>
20 <VisualState x:Name="Focused">
21 <Storyboard>
22 <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Bg"/>
23 <ColorAnimation Duration="0" To="#40FFFFFF" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="InnerBorder"/>
24 </Storyboard>
25 </VisualState>
26 </VisualStateGroup>
27 </VisualStateManager.VisualStateGroups>
28 <Rectangle Fill="{TemplateBinding Background}" RadiusY="2" RadiusX="2" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1"/>
29 <Rectangle x:Name="Bg" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#8071CBF1" StrokeThickness="1">
30 <Rectangle.Fill>
31 <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
32 <GradientStop Color="#34C5EBFF" Offset="0"/>
33 <GradientStop Color="#3481D8FF" Offset="1"/>
34 </LinearGradientBrush>
35 </Rectangle.Fill>
36 </Rectangle>
37 <Rectangle x:Name="InnerBorder" Margin="1" RadiusY="2" RadiusX="2" Stroke="Transparent"/>
38 <Grid>
39 <Grid.ColumnDefinitions>
40 <ColumnDefinition MinWidth="24" Width="Auto"/>
41 <ColumnDefinition Width="4"/>
42 <ColumnDefinition Width="*"/>
43 <ColumnDefinition Width="17"/>
44 </Grid.ColumnDefinitions>
45 <ContentPresenter Content="{TemplateBinding Icon}" Margin="1" VerticalAlignment="Center"/>
46 <ContentPresenter x:Name="Presenter" ContentTemplate="{TemplateBinding HeaderTemplate}"
47 Content="{TemplateBinding Header}" Grid.Column="2" Margin="{TemplateBinding Padding}"/>
48 <Path Grid.Column="3" Data="M 0,0 L 4,3.5 L 0,7 Z" Fill="Black"
49 Margin="4,0,0,0" VerticalAlignment="Center" Visibility="{TemplateBinding HasSubItems}"/>
50 <!--<Path x:Name="Glyph" Data="M 0,5.1 L 1.7,5.2 L 3.4,7.1 L 8,0.4 L 9.2,0 L 3.3,10.8 Z"
51 Fill="#0C12A1" FlowDirection="LeftToRight" Height="11" Width="9"/>-->
52 </Grid>
53 <Popup x:Name="PART_Popup" HorizontalOffset="{TemplateBinding ActualWidth}"
54 IsOpen="{TemplateBinding IsSubmenuOpen}" Margin="-4,0,0,0">
55 <ContentControl x:Name="SubMenuBorder">
56 <ContentControl.Template>
57 <ControlTemplate>
58 <Grid Background="#FFF5F5F5">
59 <Rectangle Fill="#F1F1F1" HorizontalAlignment="Left" RadiusY="2" RadiusX="2" Width="28"/>
60 <Rectangle Fill="#E2E3E3" HorizontalAlignment="Left" Width="1" Margin="30,0,0,0"/>
61 <Rectangle Fill="White" HorizontalAlignment="Left" Width="1" Margin="31,0,0,0"/>
62 <ContentPresenter Grid.ColumnSpan="2" Margin="1,0"/>
63 </Grid>
64 </ControlTemplate>
65 </ContentControl.Template>
66 <ScrollViewer x:Name="SubMenuScrollViewer" VerticalScrollBarVisibility="Auto" Padding="0">
67 <Grid>
68 <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
69 <Rectangle Fill="#FFF5F5F5" Height="{Binding ActualHeight, ElementName=SubMenuBorder}"
70 Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
71 </Canvas>
72 <ItemsPresenter x:Name="ItemsPresenter" Margin="2"/>
73 </Grid>
74 </ScrollViewer>
75 </ContentControl>
76 </Popup>
77 </Grid>
78 </ControlTemplate>
79 </Setter.Value>
80 </Setter>
81 </Style>

     

SuperMenuItem
using System;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace Demo
{
    public class SuperMenuItem : MenuItem
    {
        #region Fields

        private Popup popup;
        public bool CanLeave { get; set; }

        #endregion

        #region Properties

        public Visibility HasSubItems
        {
            get { return (Visibility)GetValue(HasSubItemsProperty); }
            set { SetValue(HasSubItemsProperty, value); }
        }

        public static readonly DependencyProperty HasSubItemsProperty =
            DependencyProperty.Register("HasSubItems", typeof(Visibility), typeof(SuperMenuItem), new PropertyMetadata(Visibility.Collapsed));

        public bool IsSubmenuOpen
        {
            get { return (bool)GetValue(IsSubmenuOpenProperty); }
            set { SetValue(IsSubmenuOpenProperty, value); }
        }

        public static readonly DependencyProperty IsSubmenuOpenProperty =
            DependencyProperty.Register("IsSubmenuOpen", typeof(bool), typeof(SuperMenuItem), new PropertyMetadata(false));

        #endregion

        #region Constructor

        public SuperMenuItem()
        {
            this.DefaultStyleKey = typeof(SuperMenuItem);
            this.MouseEnter += new MouseEventHandler(parent_MouseEnter);
            this.MouseLeave += new MouseEventHandler(SuperMenuItem_MouseLeave);
            this.Click += new RoutedEventHandler(SuperMenuItem_Click);
            this.CanLeave = true;
        }

        private void SuperMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (this.Parent != null && this.Parent is SuperMenuItem)
            {
                (this.Parent as SuperMenuItem).OnClick();
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            popup = (Popup)this.GetTemplateChild("PART_Popup");
            popup.Opened += new EventHandler(popup_Opened);
            popup.Closed += new EventHandler(popup_Closed);
        }

        private void popup_Opened(object sender, EventArgs e)
        {
            this.CanLeave = false;
        }

        private void popup_Closed(object sender, EventArgs e)
        {
            if (this.HasSubItems == Visibility.Visible)
            {
                this.IsSubmenuOpen = false;
            }
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                if (e.NewItems.Count > 0)
                {
                    this.HasSubItems = Visibility.Visible;
                }
            }

        }

        private void parent_MouseEnter(object sender, MouseEventArgs e)
        {
            this.CanLeave = true;
            if (this.HasSubItems == Visibility.Visible)
            {
                this.IsSubmenuOpen = true;
            }
            if (this.Parent != null && this.Parent is ContextMenu)
            {
                foreach (var item in (this.Parent as ContextMenu).Items)
                {
                    if (item != this)
                    {
                        (item as SuperMenuItem).IsSubmenuOpen = false;
                    }
                }
            }
        }

        private void SuperMenuItem_MouseLeave(object sender, MouseEventArgs e)
        {
            if (this.HasSubItems == Visibility.Visible)
            {
                if (CanLeave)
                {
                    this.IsSubmenuOpen = false;
                }
            }
        }

        #endregion
    }

}

 

所有源代码都已经附上,有需要的自己copy到项目中,不单独提供源代码下载。

posted on 2011-11-25 15:34  tanliang  阅读(3573)  评论(23编辑  收藏  举报