Comment : utiliser un menu contextuel personnalisé avec un TextBox
Cet exemple montre comment définir et implémenter un menu contextuel personnalisé simple pour un TextBox.
Définir un menu contextuel personnalisé
L’exemple XAML (Extensible Application Markup Language) suivant définit un TextBox contrôle qui inclut un menu contextuel personnalisé.
Le menu contextuel est défini à l’aide d’un ContextMenu élément. Le menu contextuel lui-même se compose d’une série d’éléments et Separator d’élémentsMenuItem. Chaque MenuItem élément définit une commande dans le menu contextuel ; l’attribut Header définit le texte d’affichage de la commande de menu et l’attribut Click spécifie une méthode de gestionnaire pour chaque élément de menu. L’élément Separator provoque simplement un 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>
Implémenter un menu contextuel personnalisé
L’exemple suivant montre le code d’implémentation de la définition de menu contextuel précédent, ainsi que le code qui active et désactive le menu contextuel. L’événement Opened est utilisé pour activer ou désactiver dynamiquement certaines commandes en fonction de l’état actuel du TextBox.
Pour restaurer le menu contextuel par défaut, utilisez la ClearValue méthode pour effacer la valeur de la ContextMenu propriété. Pour désactiver complètement le menu contextuel, définissez la ContextMenu propriété sur une référence Null (Nothing
en Visual Basic).
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;
}
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
Voir aussi
.NET Desktop feedback