Silverlight 4的是鼠标右键菜单的实现(一)

鼠标右键菜单sivlerlight 4版本以前是没法实现,在silverlight 4上微软提供了鼠标右键的响应事件,所以实现起来比较方便。鼠标右键菜单弹出的实现无非就是在该弹出菜单的地方点击右键,捕获右键消息,弹出菜单。响应和捕获右键菜单只需要在相应控件处为控件注册MouseRightButtonDownMouseRightButtonUp事件。并且在相应事件的响应函数写入如下信息。(例如下面代码中的语句)

#region Context Menu

 

        //Though we dont execute any logic on Right Mouse button down,we need to ensure the event is set to be handled to allow

        //the subsequent Right Mouse button up to be raised on the control. The context menu is displayed when the right mouse

        //button up event is raised.

        private void rtb_MouseRightButtonDown(object sender,MouseButtonEventArgs e)

        {

            e.Handled = true;

        }

 

        private void rtb_MouseRightButtonUp(object sender,MouseButtonEventArgs e)

        {

            //Construct and display the context menu

 

            RTBContextMenu menu = new RTBContextMenu(rtb);

            menu.Show(e.GetPosition(LayoutRoot));

        }

        #endregion

本文笔者以其工作经验总结出:鼠标右键有3方法实现方法,以供各位朋友参考学习。

第一种,自己绘制右键菜单

Ⅰ自己绘制右键菜单需要写一个处理菜单的基类。该基类处理类主要负责右键菜单的弹出、定位、关闭等等!代码如下)

 

 

 

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

using System.Windows.Controls.Primitives;

 

namespace SilverlightTextEditor

{

    // This is an abstract base class that captures the building block functionality for a context menu

    // including constructing and displaying a blank menu and method for closing the menu (called by default when

    // the mouse is clicked outside the context menu

 

    // Note that though this class is called ContextMenu after the most common usage for this pattern,you can use this

    // popup window to display any arbitrary control(s)/

 

    // A child class will have to implement the GetContent() method to return a FrameworkElement

    // that encapsulates the controls that you need to be displayed on the context menu.

 

    public abstract class ContextMenu

    {

        private Point _location;

        private bool _isShowing;

        private Popup _popup;

        private Grid _grid;

        private Canvas _canvas;

        private FrameworkElement _content;

 

        //Intiialize and show the popup window. This is the public method to call to display the ContextMenu at the desired location.

        public void Show(Point location)

        {

            if (_isShowing)

                throw new InvalidOperationException();

 

            _isShowing = true;

            _location = location;

            ConstructPopup();

            _popup.IsOpen = true;

        }

 

        //Close the popup window

        public void Close()

        {

            _isShowing = false;

 

            if (_popup != null)

            {

                _popup.IsOpen = false;

            }

        }

 

        //abstract function that the child class needs to implement to return the framework element that needs to be displayed in the popup window.

        protected abstract FrameworkElement GetContent();

 

        //Default behavior for OnClickOutside() is to close the context menu when there is a mouse click event outside the context menu

        protected virtual void OnClickOutside()

        {

            Close();

        }

 

        // Construct a popup window thats the size of the application with a grid layout

        // Add a canvas as a child of the grid layout to detect mouse clicks outside the context menu

        // Add the Framework Element returned by GetContent() to the grid and position it at _location

 

        private void ConstructPopup()

        {

            if (_popup != null)

                return;

 

            _popup = new Popup();

            _grid = new Grid();

 

            _popup.Child = _grid;

 

            _canvas = new Canvas();

 

            _canvas.MouseLeftButtonDown += (sender,args) => { OnClickOutside(); };

            _canvas.MouseRightButtonDown += (sender,args) => { args.Handled = true; OnClickOutside(); };

 

            _canvas.Background = new SolidColorBrush(Colors.Transparent);

 

            _grid.Children.Add(_canvas);

 

            _content = GetContent();

 

            _content.HorizontalAlignment = HorizontalAlignment.Left;

            _content.VerticalAlignment = VerticalAlignment.Top;

            _content.Margin = new Thickness(_location.X,_location.Y,0);

 

 

            _grid.Children.Add(_content);

 

            UpdateSize();

        }

 

        private void UpdateSize()

        {

            _grid.Width = Application.Current.Host.Content.ActualWidth;

            _grid.Height = Application.Current.Host.Content.ActualHeight;

 

            if (_canvas != null)

            {

                _canvas.Width = _grid.Width;

                _canvas.Height = _grid.Height;

            }

        }

    }

} 

Ⅱ右键菜单界面的实现

上面我们已经构建了一个右键菜单的处理基类,现在就让我们来写一个右键菜单的界面吧!

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Media.Effects;

using System.Windows.Media.Imaging;

 

namespace SilverlightTextEditor

{

    //Derives from the abstract class ContextMenu that provides the boilerplate code for displaying a popup window.

 

    public class RTBContextMenu : ContextMenu

    {

        RichTextBox rtb;

 

        public RTBContextMenu(RichTextBox rtb)

        {

            this.rtb = rtb;

        }

 

        //Construct the context menu and return the parent FrameworkElement.

 

        protected override FrameworkElement GetContent()

        {

            Border border = new Border() { BorderBrush = new SolidColorBrush(Color.FromArgb(255,167,171,176)),BorderThickness = new Thickness(1),Background = new SolidColorBrush(Colors.White) };

            border.Effect = new DropShadowEffect() { BlurRadius = 3,Color = Color.FromArgb(255,230,227,236) };

 

            Grid grid = new Grid() { Margin = new Thickness(1) };

            grid.ColumnDeFinitions.Add(new ColumnDeFinition() { Width = new GridLength(25) });

            grid.ColumnDeFinitions.Add(new ColumnDeFinition() { Width = new GridLength(105) });

 

            grid.Children.Add(new Rectangle() { Fill = new SolidColorBrush(Color.FromArgb(255,233,238,238)) });

            grid.Children.Add(new Rectangle() { Fill = new SolidColorBrush(Color.FromArgb(255,226,228,231)),HorizontalAlignment = HorizontalAlignment.Right,Width = 1 });

           

            //cut

            Button cutButton = new Button() { Height = 22,Margin = new Thickness(0,0),HorizontalAlignment = HorizontalAlignment.Stretch,VerticalAlignment = VerticalAlignment.Top,HorizontalContentAlignment = HorizontalAlignment.Left };

            cutButton.Style = Application.Current.Resources["ContextMenuButton"] as Style;

            cutButton.Click += cut_MouseLeftButtonUp;

            Grid.SetColumnSpan(cutButton,2);

 

            StackPanel sp = new StackPanel() { Orientation = Orientation.Horizontal };

 

            Image cutimage = new Image() { HorizontalAlignment = HorizontalAlignment.Left,Width = 16,Height = 16,Margin = new Thickness(1,0) };

            cutimage.source = new BitmapImage(new Uri("/SilverlightTextEditor;component/images/cut.png",UriKind.RelativeOrAbsolute));

            sp.Children.Add(cutimage);

 

            TextBlock cutText = new TextBlock() { Text = "Cut",HorizontalAlignment = HorizontalAlignment.Left,Margin = new Thickness(16,0) };

            sp.Children.Add(cutText);

 

            cutButton.Content = sp;

 

            grid.Children.Add(cutButton);

 

            //copy

            Button copyButton = new Button() { Height = 22,24,HorizontalContentAlignment = HorizontalAlignment.Left };

            copyButton.Style = Application.Current.Resources["ContextMenuButton"] as Style;

            copyButton.Click += copy_MouseLeftButtonUp;

            Grid.SetColumnSpan(copyButton,2);

 

            sp = new StackPanel() { Orientation = Orientation.Horizontal };

 

            Image copyImage = new Image() { HorizontalAlignment = HorizontalAlignment.Left,0) };

            copyImage.source = new BitmapImage(new Uri("/SilverlightTextEditor;component/images/copy.png",UriKind.RelativeOrAbsolute));

            sp.Children.Add(copyImage);

 

            TextBlock copyText = new TextBlock() { Text = "copy",0) };

            sp.Children.Add(copyText);

 

            copyButton.Content = sp;

 

            grid.Children.Add(copyButton);         

 

            //paste

            Button pasteButton = new Button() { Height = 22,48,HorizontalContentAlignment = HorizontalAlignment.Left };

            pasteButton.Style = Application.Current.Resources["ContextMenuButton"] as Style;

            pasteButton.Click += paste_MouseLeftButtonUp;

            Grid.SetColumnSpan(pasteButton,2);

 

            sp = new StackPanel() { Orientation = Orientation.Horizontal };

 

            Image pasteImage = new Image() { HorizontalAlignment = HorizontalAlignment.Left,0) };

            pasteImage.source = new BitmapImage(new Uri("/SilverlightTextEditor;component/images/paste.png",UriKind.RelativeOrAbsolute));

            sp.Children.Add(pasteImage);

 

            TextBlock pasteText = new TextBlock() { Text = "Paste",0) };

            sp.Children.Add(pasteText);

 

            pasteButton.Content = sp;

 

            grid.Children.Add(pasteButton);

 

            border.Child = grid;

 

            return border;

        }

 

        //

        //handle the cut,copy and paste actions when the appropriate button on the context menu is clicked.

        //

 

        void cut_MouseLeftButtonUp(object sender,RoutedEventArgs e)

        {

            Clipboard.SetText(rtb.Selection.Text);

            rtb.Selection.Text = "";

            Close();

        }

 

        void copy_MouseLeftButtonUp(object sender,RoutedEventArgs e)

        {

            Clipboard.SetText(rtb.Selection.Text);

            Close();

        }

 

        void paste_MouseLeftButtonUp(object sender,RoutedEventArgs e)

        {

            rtb.Selection.Text = Clipboard.GetText();

            Close();

        }

    }

}

通过上面右键菜单的编写我们可以通过开始所讲的构建注册右击事件的方法来实现右键菜单

相关文章

如何在Silverlight4(XAML)中绑定IsEnabled属性?我试过简单的...
我正在编写我的第一个vb.net应用程序(但我也会在这里标记c#,...
ProcessFile()是在UIThread上运行还是在单独的线程上运行.如...
我从同行那里听说,对sharepoint的了解对职业生涯有益.我们不...
我正在尝试保存一个类我的类对象的集合.我收到一个错误说明:...
我需要根据Silverlight中的某些配置值设置给定控件的Style.我...