Back to Devexpress

Commands in Rich Text Editor

windowsforms-9328-controls-and-libraries-rich-text-editor-commands.md

latest21.2 KB
Original Source

Commands in Rich Text Editor

  • Apr 12, 2023
  • 8 minutes to read

The Rich Text Editor for WinForms ships with a comprehensive set of commands associated with toolbar UI (Ribbon or Bar Command UI). These commands allow you to perform basic operations (format and edit text, create lists, add headers and footers, work with tables, and so on). All commands implemented in the Rich Text Editor control inherit from the Command object. Refer to a following topic for a full list of built-in commands: Command UI in Rich Text Editor for WinForms.

Create and Execute Commands in Code

You can create a new object that is a Command descendant to create a new command. You can also call the RichEditControl.CreateCommand method and pass the RichEditCommandId enumeration member as a parameter to create a command.

The Command class has the following methods used to execute the command action:

Command.ExecuteThe main method. Cannot be utilized when the command is disabled (call the Command.CanExecute() method to determine whether the command is enabled).Command.ForceExecuteUse this method if the command is disabled or if you want to execute the command with a parameter (for example, navigate to a page by its number). The ICommandUIState.EditValue property allows you to specify a command parameter.

The following code calls the RichEditControl.CreateCommand method to create commands based on CapitalizeEachWordTextCase, ToggleFontBold, ChangeFontBackColor, and PrintPreview commands. Each command is executed by the ForceExecute method call. The Command.CreateDefaultCommandUIState method returns the command UI state.

All commands are executed an once on a button click.

View Example

csharp
static void buttonCustomAction_ItemClick_Commands(object sender, ItemClickEventArgs e) {

    RichEditControl richEdit = e.Item.Tag as RichEditControl;
    richEdit.SelectAll();

    RichEditCommand capCommand = richEdit.CreateCommand(RichEditCommandId.CapitalizeEachWordTextCase);
    capCommand.ForceExecute(capCommand.CreateDefaultCommandUIState());

    RichEditCommand boldCommand = richEdit.CreateCommand(RichEditCommandId.ToggleFontBold);
    boldCommand.ForceExecute(boldCommand.CreateDefaultCommandUIState());

    RichEditCommand changeFontColorCommand = richEdit.CreateCommand(RichEditCommandId.ChangeFontBackColor);
    DevExpress.Utils.Commands.ICommandUIState state = changeFontColorCommand.CreateDefaultCommandUIState();
    state.EditValue = Color.Yellow;
    changeFontColorCommand.ForceExecute(state);

    RichEditCommand previewCommand = richEdit.CreateCommand(RichEditCommandId.PrintPreview);
    previewCommand.ForceExecute(previewCommand.CreateDefaultCommandUIState());

    richEdit.DeselectAll();
}
vb
Private Shared Sub buttonCustomAction_ItemClick_Commands(ByVal sender As Object, ByVal e As ItemClickEventArgs)
    Dim richEdit As RichEditControl = TryCast(e.Item.Tag, RichEditControl)
    richEdit.SelectAll()

    Dim capCommand As RichEditCommand = richEdit.CreateCommand(RichEditCommandId.CapitalizeEachWordTextCase)
    capCommand.ForceExecute(capCommand.CreateDefaultCommandUIState())

    Dim boldCommand As RichEditCommand = richEdit.CreateCommand(RichEditCommandId.ToggleFontBold)
    boldCommand.ForceExecute(boldCommand.CreateDefaultCommandUIState())

    Dim changeFontColorCommand As RichEditCommand = richEdit.CreateCommand(RichEditCommandId.ChangeFontBackColor)
    Dim state As DevExpress.Utils.Commands.ICommandUIState = changeFontColorCommand.CreateDefaultCommandUIState()
    state.EditValue = System.Drawing.Color.Yellow
    changeFontColorCommand.ForceExecute(state)

    Dim previewCommand As RichEditCommand = richEdit.CreateCommand(RichEditCommandId.PrintPreview)
    previewCommand.ForceExecute(previewCommand.CreateDefaultCommandUIState())

    richEdit.DeselectAll()
End Sub

You can bind a command to any UI element. Refer to the following articles for more information:

Best Practices

Take into account the following when you work with commands:

  • The Command UI executes commands that can throw unhandled exceptions if a problem occurs. To prevent application failure, subscribe to the RichEditControl.UnhandledException event and set the RichEditUnhandledExceptionEventArgs.Handled property to true.
  • You should always create a new instance of a command before execution. Otherwise, you may experience undesired effects and unhandled exceptions.
  • We do not recommend that you execute a disabled command. This may lead to unexpected results.

Customize Built-In Commands

To change the actions performed when the built-in command is executed, use the service substitution technique. Create the IRichEditCommandFactoryService descendant which generates custom commands and use the RichEditControl.ReplaceService<T> method (or the GetService → RemoveService → AddService method sequence) to replace default service with a newly created service.

Create A Service Descendant

The following code implements the IRichEditCommandFactoryService descendant which generates customized SaveDocumentCommand and SaveDocumentAsCommand commands. The command descendants override the ExecuteCore methods to display a message after a document is saved. The IsModified internal property indicates unsaved changes in the document. If this property is not changed to false after saving a document, it signals that the save action failed.

View Example

csharp
public class CustomRichEditCommandFactoryService : IRichEditCommandFactoryService
{
    readonly IRichEditCommandFactoryService service;
    readonly RichEditControl control;

    public CustomRichEditCommandFactoryService(RichEditControl control, IRichEditCommandFactoryService service)
    {
        Guard.ArgumentNotNull(control, "control");
        Guard.ArgumentNotNull(service, "service");
        this.control = control;
        this.service = service;
    }

    public RichEditCommand CreateCommand(RichEditCommandId id) {
        if (id == RichEditCommandId.FileSaveAs) {
            return new CustomSaveDocumentAsCommand(control);
        }
        if (id == RichEditCommandId.FileSave) {
            return new CustomSaveDocumentCommand(control);
        }
        return service.CreateCommand(id);
    }
}

public class CustomSaveDocumentCommand : SaveDocumentCommand {
    public CustomSaveDocumentCommand(IRichEditControl richEdit) : base(richEdit) { }
    protected override void ExecuteCore() {
        base.ExecuteCore();
        if (!DocumentServer.Modified) {
            MessageBox.Show("Document is saved successfully");
        }
    }
}

public class CustomSaveDocumentAsCommand : SaveDocumentAsCommand {
    public CustomSaveDocumentAsCommand(IRichEditControl richEdit) : base(richEdit) { }
    protected override void ExecuteCore() {
        DocumentServer.Modified = true;
        base.ExecuteCore();
        if (!DocumentServer.Modified) {
            MessageBox.Show("Document is saved successfully");
        }
    }
}
vb
Public Class CustomRichEditCommandFactoryService
    Implements IRichEditCommandFactoryService
    Private ReadOnly service As IRichEditCommandFactoryService
    Private ReadOnly control As RichEditControl

    Public Sub New(ByVal control As RichEditControl, ByVal service As IRichEditCommandFactoryService)
        DevExpress.Utils.Guard.ArgumentNotNull(control, "control")
        DevExpress.Utils.Guard.ArgumentNotNull(service, "service")
        Me.control = control
        Me.service = service
    End Sub

    Public Function CreateCommand(ByVal id As RichEditCommandId) As RichEditCommand Implements IRichEditCommandFactoryService.CreateCommand
        If id.Equals(RichEditCommandId.FileSaveAs) Then
            Return New CustomSaveDocumentAsCommand(control)
        End If
        If id.Equals(RichEditCommandId.FileSave) Then
            Return New CustomSaveDocumentCommand(control)
        End If
        Return service.CreateCommand(id)
    End Function
End Class

Public Class CustomSaveDocumentCommand
    Inherits SaveDocumentCommand
    Public Sub New(ByVal richEdit As IRichEditControl)
        MyBase.New(richEdit)
    End Sub

    Protected Overrides Sub ExecuteCore()
        MyBase.ExecuteCore()
        If (Not DocumentServer.Modified) Then
            MessageBox.Show("Document is saved successfully")
        End If
    End Sub
End Class

Public Class CustomSaveDocumentAsCommand
    Inherits SaveDocumentAsCommand
    Public Sub New(ByVal richEdit As IRichEditControl)
        MyBase.New(richEdit)
    End Sub

    Protected Overrides Sub ExecuteCore()
        DocumentServer.Modified = True
        MyBase.ExecuteCore()
        If (Not DocumentServer.Modified) Then
            MessageBox.Show("Document is saved successfully")
        End If
    End Sub
End Class

Substitute the Service

The following code replaces the IRichEditCommandFactoryService service with its customized descendant.

View Example

csharp
var builtInService = richEditControl1.GetService<IRichEditCommandFactoryService>();
var myCommandFactory = new CustomRichEditCommandFactoryService(richEditControl1,builtInService);
richEditControl1.ReplaceService<IRichEditCommandFactoryService>(myCommandFactory);
vb
Dim builtInService = richEditControl1.GetService(Of IRichEditCommandFactoryService)()
Dim myCommandFactory = New CustomRichEditCommandFactoryService(richEditControl1,builtInService)
richEditControl1.ReplaceService(Of IRichEditCommandFactoryService)(myCommandFactory)

Change Shortcut Keys

The commands in Rich Text Editor ship with assigned keyboard shortcuts. You can use the RichEditControl.RemoveShortcutKey and the RichEditControl.AssignShortcutKeyToCommand methods to modify shortcut keys assigned to commands. Refer to the following article for a full list of available shortcuts: Keyboard Shortcuts

The following code assigns Ctrl+G shortcut to ToggleShowWhitespaceCommand and removes predefined Ctrl+N shortcut so that it is no longer in use.

View Example

csharp
using System.Windows.Forms;

richEditControl.Text = "Use 'Ctrl+G' shortcut to show/hide whitespace characters";
richEditControl.Text += "\r\nYou can no longer use the 'Ctrl+N' shortcut to create a new document.";

richEditControl.AssignShortcutKeyToCommand(Keys.Control, Keys.G, RichEditCommandId.ToggleShowWhitespace);
richEditControl.RemoveShortcutKey(Keys.Control, Keys.N);
vb
Imports System.Windows.Forms

richEditControl.Text = "Use 'Ctrl+G' shortcut to show/hide whitespace characters"
richEditControl.Text += Constants.vbCrLf & "You can no longer use the 'Ctrl+N' shortcut to create a new document"

richEditControl.AssignShortcutKeyToCommand(Keys.Control, Keys.G, RichEditCommandId.ToggleShowWhitespace)
richEditControl.RemoveShortcutKey(Keys.Control, Keys.N)

Disable Built-In Commands

Restrict Operations

Use the RichEditControl.BehaviorOptions and DocumentOptions.DocumentCapabilities properties to disable certain functionality and their commands in the Rich Text Editor.

The table below lists options and the operations they manage:

FunctionalityOption
Create new documentsRichEditBehaviorOptions.CreateNew
Open documentsRichEditBehaviorOptions.Open
Save documentsRichEditBehaviorOptions.Save
RichEditBehaviorOptions.SaveAs
PrintingRichEditBehaviorOptions.Printing
EncryptionRichEditBehaviorOptions.Encrypt
Clipboard operationsRichEditBehaviorOptions.Copy
RichEditBehaviorOptions.Cut
RichEditBehaviorOptions.Paste
Undo operationsDocumentCapabilitiesOptions.Undo
Page layout (page breaks, margins, columns, orientation, line numbering)DocumentCapabilitiesOptions.Sections
TablesDocumentCapabilitiesOptions.Tables
Headers and footersDocumentCapabilitiesOptions.HeadersFooters
Track ChangesDocumentCapabilitiesOptions.TrackChanges
CommentsDocumentCapabilitiesOptions.Comments
Footnotes and endnotesDocumentCapabilitiesOptions.EndNotes
DocumentCapabilitiesOptions.FootNotes
Fields (including mail merge)DocumentCapabilitiesOptions.Fields
Text formattingDocumentCapabilitiesOptions.CharacterFormatting
DocumentCapabilitiesOptions.CharacterStyle
DocumentCapabilitiesOptions.ParagraphFormatting
DocumentCapabilitiesOptions.ParagraphStyle
ListsDocumentCapabilitiesOptions.Numbering

Run Demo: Operation Restrictions

The code sample below hides all printing and page layout commands and disables zooming commands in a Ribbon UI:

csharp
using DevExpress.XtraRichEdit;
//...

HideCommands(richEditControl1.Options);
//...

private void HideCommands(RichEditControlOptions options)
{
    options.Behavior.Printing= DocumentCapability.Hidden;
    options.DocumentCapabilities.Sections = DocumentCapability.Hidden;
    options.Behavior.Zooming = DocumentCapability.Disabled;
}
vb
Imports DevExpress.XtraRichEdit
'...

HideCommands(richEditControl1.Options)
'...

Private Sub HideCommands(ByVal options As RichEditControlOptions)
    options.Behavior.Printing= DocumentCapability.Hidden
    options.DocumentCapabilities.Sections = DocumentCapability.Hidden
    options.Behavior.Zooming = DocumentCapability.Disabled
End Sub

Disable or Hide a Command with the Specified Condition

You can disable or hide a command when meeting the specified criteria. Create a custom command and override its UpdateCommandUIState method. Change the state depending on the required condition. Set the ICommandUIState.Enabled property to false to disable the command; set the ICommandUIState.Visible property to false to hide the command.

The code sample below creates a custom Replace command and disables it if the document is protected:

csharp
public class CustomReplaceCommand : ReplaceCommand {
    public CustomReplaceCommand(IRichEditControl control) : base(control)
    {
    }
    public override void UpdateUIState(ICommandUIState state)
    {
        base.UpdateUIState(state);
        if (this.Control.Document.IsDocumentProtected)
            state.Enabled = false;
    }
}

public class CustomRichEditCommandFactoryService : IRichEditCommandFactoryService {
    readonly IRichEditCommandFactoryService service;
    readonly RichEditControl control;

    public CustomRichEditCommandFactoryService(RichEditControl control, IRichEditCommandFactoryService service)
    {
        DevExpress.Utils.Guard.ArgumentNotNull(control, "control");
        DevExpress.Utils.Guard.ArgumentNotNull(service, "service");
        this.control = control;
        this.service = service;
    }

    public RichEditCommand CreateCommand(RichEditCommandId id)
    {
        if (id == RichEditCommandId.Replace)
            return new CustomReplaceCommand(control);
        return service.CreateCommand(id);
    }
}
vb
Public Class CustomReplaceCommand
    Inherits ReplaceCommand

    Public Sub New(ByVal control As IRichEditControl)
        MyBase.New(control)
    End Sub
    Public Overrides Sub UpdateUIState(ByVal state As ICommandUIState)
        MyBase.UpdateUIState(state)
        If Me.Control.Document.IsDocumentProtected Then
            state.Enabled = False
        End If
    End Sub
End Class

Public Class CustomRichEditCommandFactoryService
Implements IRichEditCommandFactoryService

Private ReadOnly service As IRichEditCommandFactoryService
Private ReadOnly control As RichEditControl

Public Sub New(ByVal control As RichEditControl, ByVal service As IRichEditCommandFactoryService)
    DevExpress.Utils.Guard.ArgumentNotNull(control, "control")
    DevExpress.Utils.Guard.ArgumentNotNull(service, "service")
    Me.control = control
    Me.service = service
End Sub

Public Function CreateCommand(ByVal id As RichEditCommandId) As RichEditCommand
    If id = RichEditCommandId.Replace Then
        Return New CustomReplaceCommand(control)
    End If
    Return service.CreateCommand(id)
End Function
End Class