Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

How to: Use a Custom Context Menu with a TextBox

This example shows how to define and implement a simple custom context menu for a TextBox.

Example

The following Extensible Application Markup Language (XAML) example defines a TextBox control that includes a custom context menu.

The context menu is defined using a ContextMenu element. The context menu itself consists of a series of MenuItem elements and Separator elements. Each MenuItem element defines a command in the context menu; the Header attribute defines the display text for the menu command, and the Click attribute specifies a handler method for each menu item. The Separator element simply causes a separating line to be rendered between the previous and subsequent menu items.

<TextBox
  Name="cxmTextBox" 
  Grid.Row="1"
  AcceptsReturn="True"
  AcceptsTab="True"
  VerticalScrollBarVisibility="Visible"
  TextWrapping="Wrap"
>
  <TextBox.ContextMenu>
    <ContextMenu 
      Name="cxm"
      Opened="CxmOpened"
    >
      <MenuItem 
        Header="Cut"
        Name="cxmItemCut" 
        Click="ClickCut" 
      />
      <MenuItem 
        Header="Copy" 
        Name="cxmItemCopy"
        Click="ClickCopy" 
      />
      <MenuItem 
        Header="Paste"
        Name="cxmItemPaste"
        Click="ClickPaste" 
      />
      <Separator/>
      <MenuItem 
        Header="Select All"
        Name="cxmItemSelectAll"
        Click="ClickSelectAll" 
      />
      <MenuItem 
        Header="Select Current Line"
        Name="cxmItemSelectLine"
        Click="ClickSelectLine" 
      />
      <Separator/>
      <MenuItem 
        Header="Undo Last Action"
        Name="cxmItemUndo"
        Click="ClickUndo" 
      />
      <MenuItem 
        Header="Redo Last Action"
        Name="cxmItemRedo"
        Click="ClickRedo" 
      />
      <Separator/>
      <MenuItem 
        Header="Clear All Text"
        Name="cxmItemClear"
        Click="ClickClear" 
      />
    </ContextMenu>
  </TextBox.ContextMenu>
  This TextBox uses a simple custom context menu.  The context menu can be disabled by checking
  the CheckBox above, which simply sets the TextBox.ContextMenu property to null.
</TextBox>

The following example shows the implementation code for the context menu defined above, as well as the code that enables and disables the context menu. The Opened event is used to dynamically enable or disable certain commands depending on the current state of the TextBox.

To restore the default context menu use the ClearValue method to clear the value of the ContextMenu property. To disable the context menu altogether, set the ContextMenu property to null.

void MenuChange(Object sender, RoutedEventArgs ags)
{
    RadioButton rb = sender as RadioButton;
    if (rb == null || cxm == null) return;

    switch (rb.Name)
    {
        case "rbCustom":
            cxmTextBox.ContextMenu = cxm;
            break;
        case "rbDefault":
            // Clearing the value of the ContextMenu property
            // restores the default TextBox context menu.
            cxmTextBox.ClearValue(ContextMenuProperty);
            break;
        case "rbDisabled":
            // Setting the ContextMenu propety to 
            // null disables the context menu.
            cxmTextBox.ContextMenu = null;
            break;
        default:
            break;
    }

}

void ClickPaste(Object sender, RoutedEventArgs args)     { cxmTextBox.Paste(); }
void ClickCopy(Object sender, RoutedEventArgs args)      { cxmTextBox.Copy(); }
void ClickCut(Object sender, RoutedEventArgs args)       { cxmTextBox.Cut(); }
void ClickSelectAll(Object sender, RoutedEventArgs args) { cxmTextBox.SelectAll(); }
void ClickClear(Object sender, RoutedEventArgs args)     { cxmTextBox.Clear(); } 
void ClickUndo(Object sender, RoutedEventArgs args)      { cxmTextBox.Undo(); }
void ClickRedo(Object sender, RoutedEventArgs args)      { cxmTextBox.Redo(); }

void ClickSelectLine(Object sender, RoutedEventArgs args)
{
    int lineIndex = cxmTextBox.GetLineIndexFromCharacterIndex(cxmTextBox.CaretIndex);
    int lineStartingCharIndex = cxmTextBox.GetCharacterIndexFromLineIndex(lineIndex);
    int lineLength = cxmTextBox.GetLineLength(lineIndex);
    cxmTextBox.Select(lineStartingCharIndex, lineLength);
}

void CxmOpened(Object sender, RoutedEventArgs args)
{
    // Only allow copy/cut if something is selected to copy/cut.
    if (cxmTextBox.SelectedText == "")
        cxmItemCopy.IsEnabled = cxmItemCut.IsEnabled = false;
    else
        cxmItemCopy.IsEnabled = cxmItemCut.IsEnabled = true;

    // Only allow paste if there is text on the clipboard to paste.
    if (Clipboard.ContainsText())
        cxmItemPaste.IsEnabled = true;
    else
        cxmItemPaste.IsEnabled = false;
}

See Also

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

Show:
© 2014 Microsoft