Gewusst wie: Verwenden eines benutzerdefinierten Kontextmenüs mit "TextBox"

Aktualisiert: November 2007

Dieses Beispiel zeigt, wie Sie für ein TextBox-Steuerelement ein einfaches benutzerdefiniertes Kontextmenü definieren und implementieren.

Beispiel

Im folgenden Extensible Application Markup Language (XAML)-Beispiel wird ein TextBox-Steuerelement definiert, das ein benutzerdefiniertes Kontextmenü enthält.

Das Kontextmenü wird mithilfe eines ContextMenu-Elements definiert. Das Kontextmenü selbst besteht aus einer Reihe von MenuItem-Elementen und Separator-Elementen. Jedes MenuItem-Element definiert einen Befehl im Kontextmenü. Das Header-Attribut definiert den Anzeigetext für den Menübefehl, und das Click-Attribut gibt für jedes Menüelement eine Handlermethode an. Das Separator-Element bewirkt lediglich, dass zwischen dem vorherigen und dem nachfolgenden Menüelement eine Linie eingefügt wird.

<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>

Das folgende Beispiel zeigt den Implementierungscode für die oben angegebene Kontextmenüdefinition sowie den Code an, der das Kontextmenü aktiviert bzw. deaktiviert. Das Opened-Ereignis wird verwendet, um bestimmte Befehle in Abhängigkeit vom aktuellen Zustand der TextBox dynamisch zu aktivieren bzw. zu deaktivieren.

Zum Wiederherstellen des standardmäßigen Kontextmenüs verwenden Sie die ClearValue-Methode, um den Wert der ContextMenu-Eigenschaft zu löschen. Zum vollständigen Deaktivieren des Kontextmenüs setzen Sie die ContextMenu-Eigenschaft auf einen NULL-Verweis (Nothing in Visual Basic).

Private Sub MenuChange(ByVal sender As Object, ByVal args As RoutedEventArgs)
    Dim rb As RadioButton = CType(sender, RadioButton)
    If myGrid.Children.Contains(cxmTextBox) Then
        Select Case rb.Name
            Case "rbCustom"
                cxmTextBox.ContextMenu = cxm
            Case "rbDefault"
                'Clearing the value of the ContextMenu property
                'restores the default TextBox context menu.
                cxmTextBox.ClearValue(ContextMenuProperty)
            Case "rbDisabled"
                'Setting the ContextMenu propety to 
                'null disables the context menu.
                cxmTextBox.ContextMenu = Nothing
        End Select
    Else : Return
    End If
End Sub

Private Sub ClickPaste(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Paste()
End Sub
Private Sub ClickCopy(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Copy()
End Sub
Private Sub ClickCut(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Cut()
End Sub
Private Sub ClickSelectAll(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.SelectAll()
End Sub
Private Sub ClickClear(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Clear()
End Sub
Private Sub ClickUndo(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Undo()
End Sub
Private Sub ClickRedo(ByVal sender As Object, ByVal args As RoutedEventArgs)
    cxmTextBox.Redo()
End Sub
Private Sub ClickSelectLine(ByVal sender As Object, ByVal args As RoutedEventArgs)
    Dim lineIndex As Integer = cxmTextBox.GetLineIndexFromCharacterIndex(cxmTextBox.CaretIndex)
    Dim lineStartingCharIndex As Integer = cxmTextBox.GetCharacterIndexFromLineIndex(lineIndex)
    Dim lineLength As Integer = cxmTextBox.GetLineLength(lineIndex)
    cxmTextBox.Select(lineStartingCharIndex, lineLength)
End Sub
Private Sub CxmOpened(ByVal sender As Object, ByVal args As RoutedEventArgs)
    'Only allow copy/cut if something is selected to copy/cut.
    If cxmTextBox.SelectedText = "" Then
        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() Then
            cxmItemPaste.IsEnabled = True
        Else
            cxmItemPaste.IsEnabled = False
        End If
    End If
End Sub
private 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;
}

Siehe auch

Aufgaben

Gewusst wie: Verwenden der Rechtschreibprüfung mit einem Kontextmenü

Konzepte

Übersicht über TextBox

Übersicht über RichTextBox