Click here to Skip to main content
12,632,322 members (27,356 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

43.7K views
810 downloads
17 bookmarked
Posted

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

, 30 Mar 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
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

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

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

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)

Share

About the Author

Anil_Saran
Software Developer (Senior)
India India
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionSilverlight Toolkit? Pin
BillVo26-Oct-11 13:01
memberBillVo26-Oct-11 13:01 
AnswerRe: Silverlight Toolkit? Pin
Anil_Saran15-Nov-11 18:30
memberAnil_Saran15-Nov-11 18:30 
GeneralPopupMenu Class Pin
Ziad J.khan24-May-10 9:16
memberZiad J.khan24-May-10 9:16 
GeneralMy vote of 1 Pin
VickyC#22-Apr-10 2:29
memberVickyC#22-Apr-10 2:29 
GeneralCopy Paste SHape object. Pin
Anil Pandey13-Apr-10 21:19
memberAnil Pandey13-Apr-10 21:19 
GeneralRe: Copy Paste SHape object. Pin
Anil_Saran14-Apr-10 21:52
memberAnil_Saran14-Apr-10 21:52 
GeneralRe: Copy Paste SHape object. Pin
Anil Pandey14-Apr-10 21:54
memberAnil Pandey14-Apr-10 21:54 
GeneralRe: Copy Paste SHape object. Pin
Anil_Saran14-Apr-10 21:57
memberAnil_Saran14-Apr-10 21:57 
GeneralGood concept..This idea can be used for developing other rich user controls Pin
SureshGubba31-Mar-10 0:31
memberSureshGubba31-Mar-10 0:31 
GeneralRe: Good concept..This idea can be used for developing other rich user controls Pin
Anil_Saran3-Apr-10 2:25
memberAnil_Saran3-Apr-10 2:25 
GeneralNice Article. Pin
Sumi .D30-Mar-10 19:09
memberSumi .D30-Mar-10 19:09 
GeneralRe: Nice Article. Pin
Anil_Saran3-Apr-10 2:25
memberAnil_Saran3-Apr-10 2: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 10:11
memberMohammad Elsheimy30-Mar-10 10: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 2:24
memberAnil_Saran3-Apr-10 2: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 5:03
memberMohammad Elsheimy3-Apr-10 5: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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161208.2 | Last Updated 30 Mar 2010
Article Copyright 2010 by Anil_Saran
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid