HOW TO:在文字方塊使用自訂內容功能表
更新:2007 年 11 月
本範例示範如何定義及實作 TextBox 的簡單自訂內容功能表。
範例
下列可延伸標記語言 (XAML) 範例定義包含自訂內容功能表的 TextBox 控制項。
內容功能表是使用 ContextMenu 項目來定義。內容功能表本身則由一系列的 MenuItem 項目和 Separator 項目所組成。每個 MenuItem 項目各定義內容功能表中的一個命令,Header 屬性 (Attribute) 定義功能表命令的顯示文字,而 Click 屬性則指定每個功能表項目的處理常式方法。Separator 項目只會在前一個和後續功能表項目之間顯示一條分隔線。
<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>
下列範例顯示前述內容功能表定義的實作程式碼,以及啟用及停用內容功能表的程式碼。Opened 事件會依據 TextBox 目前的狀態,動態啟用或停用特定命令。
若要還原預設內容功能表,請使用 ClearValue 方法清除 ContextMenu 屬性的值。若要完全停用內容功能表,請將 ContextMenu 屬性設定為 null 參考 (在 Visual Basic 中則為 Nothing)。
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;
}