Click here to Skip to main content
15,881,204 members
Articles / Programming Languages / C#

Custom Silverlight TextBox with contextmenu (Cut, Copy, Paste and Delete)

Rate me:
Please Sign up or sign in to vote.
4.64/5 (15 votes)
30 Mar 2010CPOL2 min read 67.3K   858   17   15
This article describes a basic functionality of textbox with cut, copy, paste and delete using context menu which might be helpful to enrich user experience and assist developers.

Introduction

  1. Silverlight 4 (Beta)
  2. VS2010 (Beta)
  3. .NET Framework 4.0 (Beta)

This article describes a basic functionality of textbox with cut, copy, paste and delete using context menu which might be helpful to enrich user experience and assist developers.
By default, Silverlight does not provide a context menu.
first.JPG
Second.JPG

This article is an attempt to solve the interesting but important problem in Silverlight textbox.
Also works as both plug-in Silverlight and out of browser..

Background

Silverlight 4 now enables MouseRightButtonUp/Down events to attach and handle. This allows the developer to take control over what he/she likes to do when those events occur (for example, context style menus functionality within the application).

Third.JPG
However, context menu is not provided by Silverlight because it requires to be user initiated called by an application in response to user input. More details can be found at Security Overview of Silverlight 4.

Using the Code

<CustomPlaceHolder> Class

C#
Public abstract class CustomPlaceHolder
{
        private Point _location;
        private bool _isShowing;
        private Popup _popup;
        private Grid _grid;
        private FrameworkElement _content;

        public void Show(Point location)
        {
            if (_isShowing)
                throw new InvalidOperationException();

            _isShowing = true;
            _location = location;
            DisplayPopup();
            _popup.IsOpen = true;
        }

        public void Close()
        {
            _isShowing = false;
            if (_popup != null)
                _popup.IsOpen = false;
        }

        private void DisplayPopup()
        {
            _popup = new Popup();
            _grid = new Grid();
            _popup.Child = _grid;
            _content = GetContent();
            _content.HorizontalAlignment = HorizontalAlignment.Left;
            _content.VerticalAlignment = VerticalAlignment.Top;
            _content.Margin = new Thickness(_location.X, _location.Y, 0, 0);
            _grid.Children.Add(_content);
        }

        #region Abstract and Virtual
        protected abstract FrameworkElement GetContent();
        protected virtual void OnClickOutside() { }
        #endregion //Abstract and  Virtual           //

This abstract base class is used to create a popup menu irrespective of what kind of controls are going to be placed inside. This just acts as a placeholder or could be called a container.

<CustomContextMenu : CustomPlaceHolder> Class

C#
Public abstract class CustomContextMenu : CustomPlaceHolder
{
        protected override FrameworkElement GetContent()
        {
            Grid grid = new Grid()
            {
                Width = 100,
                Height = 100
            };
            Border border = new Border()
            {
                BorderBrush = new SolidColorBrush(Colors.Black),
                BorderThickness = new Thickness(1),
                Background = new SolidColorBrush(Colors.LightGray)
            };
            _options = new ListBox();
            AddToListBox();
            grid.Children.Add(_options);
            return grid;
        }

        private void AddToListBox()
        {
            TextBlock cut = new TextBlock()
            {
                Text = "Cut",
                Width = 90
            };
            cut.MouseLeftButtonDown += 
		new System.Windows.Input.MouseButtonEventHandler
			(cut_MouseLeftButtonDown);
            TextBlock copy = new TextBlock()
            {
                Text = "Copy",
                Width = 90
            };
            copy.MouseLeftButtonDown += 
		new System.Windows.Input.MouseButtonEventHandler
			(copy_MouseLeftButtonDown);
            TextBlock paste = new TextBlock()
            {
                Text = "Paste",
                Width = 90
            };
            paste.MouseLeftButtonDown += 
		new System.Windows.Input.MouseButtonEventHandler
			(paste_MouseLeftButtonDown);
            TextBlock delete = new TextBlock()
            {
                Text = "Delete",
                Width = 90
            };
            delete.MouseLeftButtonDown += 
		new System.Windows.Input.MouseButtonEventHandler
			(delete_MouseLeftButtonDown);
            if (string.IsNullOrEmpty(_textBox.SelectedText))
            {
                cut.Foreground = new SolidColorBrush(Colors.Gray);
                copy.Foreground = new SolidColorBrush(Colors.Gray);
                delete.Foreground = new SolidColorBrush(Colors.Gray);
            }
            _options.Items.Add(cut);
            _options.Items.Add(copy);
            _options.Items.Add(paste);
            _options.Items.Add(delete);
        }        

The CustomContextMenu class inherits from CustomPlaceHolder class and implements GetContent() of base class. In derived class AddToListBox() function will set the type of control which is going to display inside popup menu. Currently, I am using TextBlock control to display as ListBox content.

<CustomTextBox > Class

C#
Public class CustomTextBox:TextBox
{
         CustomContextMenu contextMenu;

         private void CustomContextMenu()
        {
            this.MouseRightButtonDown +=
		new System.Windows.Input.MouseButtonEventHandler
			(CustomTextBox_MouseRightButtonDown);
            this.MouseRightButtonUp +=
		new System.Windows.Input.MouseButtonEventHandler
			(CustomTextBox_MouseRightButtonUp);
        }

         void CustomTextBox_MouseRightButtonUp
		(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (contextMenu == null)
            {
                contextMenu = new CustomContextMenu(this);
                contextMenu.Show(e.GetPosition(null));
            }
            else
            {
                contextMenu.Close();
                contextMenu.Show(e.GetPosition(null));
            }
        }

        void CustomTextBox_MouseRightButtonDown
		(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.Focus();
            e.Handled = true;
        }

        void Content_Resized(object sender, EventArgs e)
       {
            HtmlElement element = HtmlPage.Document.GetElementById("htmlBody");
            if (element != null)
            {
               element.AttachEvent("mousedown",
		new EventHandler<HtmlEventArgs>(RaiseHtmlEvent));
            }

            CloseCustomContextMenu();
        }
}

Here, CustomTextBox class derived from TextBox control provides context menu when user right clicks inside textbox. And to Setfocus (blink cursor when user clicks inside textbox) on customtextbox, we have to override OnGotFocus() function.

In this class, CustomContextMenu uses as member variable and gets initialized and gets active when right clicking inside textbox (MouseRightButtonDown/Up event).
To fire MouseRightButtonDown event make sure inside the event MouseRightButtonUp e.handled=true is set, else it won’t fire the event.

An important note: Just add this tag <body id="htmlBody"> to *.aspx page where Silverlight control is hosted. As in the above class, to track the “mousedown” event which will help to close the context menu when user clicks outside the Silverlight control (i.e on aspx/HTML page).

For those who are new to Silverlight and want to run out-of browser application, here are a few ways:

  1. Either right click on the application or click on “Install” button (If this is not installed on local machine will enable, else disable).

    Fourth.JPG

  2. Once clicked, it will pop-up a Security warning. Click on install.

    Fifth.JPG

  3. After this GoTo - Start-> All Programs: will display the below image:

    Sixth.JPG

Further Reading

History

  • 30th March, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSilverlight Toolkit? Pin
BillVo26-Oct-11 12:01
BillVo26-Oct-11 12:01 
Well done, Anil!

I'd love to see someone achieve this same result using the Silverlight Toolkit on Codeplex (silverlight.codeplex.com). The toolkit has beautiful a ContextMenu, but it's not integrated so nicely with Textbox as this solution.

Bill
AnswerRe: Silverlight Toolkit? Pin
Anil_Saran15-Nov-11 17:30
Anil_Saran15-Nov-11 17:30 
GeneralPopupMenu Class Pin
Ziad J.khan24-May-10 8:16
professionalZiad J.khan24-May-10 8:16 
GeneralMy vote of 1 Pin
VickyC#22-Apr-10 1:29
VickyC#22-Apr-10 1:29 
GeneralCopy Paste SHape object. Pin
Anil Pandey13-Apr-10 20:19
Anil Pandey13-Apr-10 20:19 
GeneralRe: Copy Paste SHape object. Pin
Anil_Saran14-Apr-10 20:52
Anil_Saran14-Apr-10 20:52 
GeneralRe: Copy Paste SHape object. Pin
Anil Pandey14-Apr-10 20:54
Anil Pandey14-Apr-10 20:54 
GeneralRe: Copy Paste SHape object. Pin
Anil_Saran14-Apr-10 20:57
Anil_Saran14-Apr-10 20:57 
GeneralGood concept..This idea can be used for developing other rich user controls Pin
SureshGubba30-Mar-10 23:31
SureshGubba30-Mar-10 23:31 
GeneralRe: Good concept..This idea can be used for developing other rich user controls Pin
Anil_Saran3-Apr-10 1:25
Anil_Saran3-Apr-10 1:25 
GeneralNice Article. Pin
Sumi .D30-Mar-10 18:09
Sumi .D30-Mar-10 18:09 
GeneralRe: Nice Article. Pin
Anil_Saran3-Apr-10 1:25
Anil_Saran3-Apr-10 1:25 
Generalreally a great article, thank you. what about a drop-shadow for the menu? (btw, what is "custome"? please correct it.) Pin
Mohammad Elsheimy30-Mar-10 9:11
Mohammad Elsheimy30-Mar-10 9:11 
GeneralRe: really a great article, thank you. what about a drop-shadow for the menu? (btw, what is "custome"? please correct it.) Pin
Anil_Saran3-Apr-10 1:24
Anil_Saran3-Apr-10 1:24 
GeneralRe: really a great article, thank you. what about a drop-shadow for the menu? (btw, what is "custome"? please correct it.) Pin
Mohammad Elsheimy3-Apr-10 4:03
Mohammad Elsheimy3-Apr-10 4:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.