Comment : utiliser un menu contextuel personnalisé avec un TextBox
Mise à jour : novembre 2007
Cet exemple montre comment définir et implémenter un menu contextuel personnalisé simple pour un contrôle TextBox.
Exemple
L'exemple XAML (Extensible Application Markup Language) suivant définit un contrôle TextBox qui inclut un menu contextuel personnalisé.
Le menu contextuel est défini à l'aide d'un élément ContextMenu. Le menu contextuel lui-même est constitué d'une série d'éléments MenuItem et Separator. Chaque élément MenuItem définit une commande du menu contextuel ; l'attribut Header définit le texte affiché pour la commande de menu, tandis que l'attribut Click spécifie une méthode de gestionnaire pour chaque élément de menu. L'élément Separator provoque simplement le rendu d'une ligne de séparation entre les éléments de menu précédents et suivants.
<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>
L'exemple suivant montre le code d'implémentation pour la définition de menu contextuel précédente, de même que le code qui active et désactive le menu contextuel. L'événement Opened est utilisé pour activer ou désactiver certaines commandes de manière dynamique selon l'état actuel de TextBox.
Pour restaurer le menu contextuel par défaut, utilisez la méthode ClearValue pour effacer la valeur de la propriété ContextMenu. Pour désactiver complètement le menu contextuel, affectez une référence nulle (Nothing dans Visual Basic) à la propriété ContextMenu.
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;
}
Voir aussi
Tâches
Comment : utiliser la vérification de l'orthographe avec un menu contextuel