Intersoft ClientUI Documentation
Walkthrough: Create Consistent UI for Rich Text Editor using Routed Command

This walkthrough shows you how to create consistent UI for rich text editor using Routed Command.

 This walkthrough demonstrate the following concept:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new ClientUI Application Project

The first step is to create a new ClientUI Application project using Intersoft ClientUI Application project template in Visual Studio.

To create the ClientUI Application project

  1. Start Visual Studio 2010.
  2. Create a new ClientUI Application project using Intersoft ClientUI Application project template. To learn more, see Walkthrough: Create New Intersoft ClientUI Application Template.

To add the resources file

  1. In your project, create new folder with name Assets.
  2. In Assets folder, create new folder with name Images.
  3. In Images folder, copy the images from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Images\Office].
  4. In Images folder, copy the Edit.png image from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.ClientUIFramework\Assets\Images].

Creating the View

This section steps you through the process of creating a page that uses a variety of ClientUI controls such as UXMenuBar, UXSeparator, UXDockTray, UXContextMenu, UXMenuItem, UXToolBar, and UXToolBarButton. All the various UI Controls is used to execute the command which implement a cut, copy, paste and etc inside the rich text editor.

To create the View

  1. Add the UXWindow component from Intersoft ClientUI. Set the following properties of UXWindow as below.
    Properties Value
    Header Intersoft Press - New Document
    Width 480
    Height 280
    CanMaximize False
    CanMinimize False
    CanClose False
    IsActive True
    IsClientVisible True
    Icon Edit.png
  2. Add a DockPanel inside the UXWindow. Reset all properties by right-clicking on the DockPanel, choose Reset Layout and select All .
     
  3. Add the UXMenuBar inside the DockPanel. Reset all properties of UXMenuBar and set the following properties as below.
    Properties Value
    DockPanel.Dock Top
    AccessModifiers Control, Alt
  4. Add the UXMenuItem inside the UXMenuBar. Set the following properties of UXMenuItem as below.
    Properties Value
    Header _File
    HorizontalAlignment Left
    VerticalAlignment Top
  5. Add the UXMenuItem inside the UXMenuItem. Set the following properties of UXMenuItem as below.
    Properties Value
    Header _New
    InputGestureText Ctrl+Shift+N
    Icon NewDocumentHS.png

    XAML
    Copy Code
    <Grid x:Name="LayoutRoot">
        <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Edit.png" >
            <Grid>
                <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
                    <Intersoft:UXMenuBar Name="uXMenuBar1" Intersoft:DockPanel.Dock="Top" AccessModifiers="Control, Alt">
                        <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">
                          <Intersoft:UXMenuItem Header="_New" InputGestureText="Ctrl+Shift+N" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/NewDocumentHS.png" />
                        </Intersoft:UXMenuItem>
                    </Intersoft:UXMenuBar>
                </Intersoft:DockPanel>
            </Grid>
        </Intersoft:UXWindow>
    </Grid>
  6. Add another sub-menu item for Open, Save, Save As, Page Set up..., Print... and Exit as you have created in the previous step.
    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">    <Intersoft:UXMenuBar Name="uXMenuBar1" Intersoft:DockPanel.Dock="Top" AccessModifiers="Control, Alt">        <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">            <Intersoft:UXMenuItem Header="_New" InputGestureText="Ctrl+Shift+N" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/NewDocumentHS.png" />            <Intersoft:UXMenuItem Header="_Open..." Icon="/RichEditorRoutedCommands;component/Images/Office/OpenFile.png"/>            <Intersoft:UXMenuItem Header="_Save" InputGestureText="Ctrl+Shift+S" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/SaveHS.png"/>            <Intersoft:UXMenuItem Header="Save _As..."/>            <Intersoft:UXSeparator/>            <Intersoft:UXMenuItem Header="Page Set_up..."/>            <Intersoft:UXMenuItem Header="_Print..."/>            <Intersoft:UXSeparator/>            <Intersoft:UXMenuItem Header="E_xit"/>         </Intersoft:UXMenuItem>    </Intersoft:UXMenuBar></Intersoft:DockPanel>

  7. Add a menu item called Edit and sub-menu items for Undo, Cut, Copy, Paste, DeleteSelect All and Time/Date as you repeat steps number 4-5.
    XAML
    Copy Code
     <Grid x:Name="LayoutRoot">        <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Edit.png" >            <Grid>                <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">                    ...                    <Intersoft:UXMenuItem Header="_Edit">                        <Intersoft:UXMenuItem Header="_Undo" IsEnabled="False"/>                        <Intersoft:UXSeparator/>                        <Intersoft:UXMenuItem Header="Cu_t" IsEnabled="False" InputGestureText="Ctrl+Shift+X" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CutHS.png"/>                        <Intersoft:UXMenuItem Header="_Copy" IsEnabled="False" InputGestureText="Ctrl+Shift+C" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CopyHS.png"/>                        <Intersoft:UXMenuItem Header="_Paste" IsEnabled="False" InputGestureText="Ctrl+Shift+V" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PasteHS.png"/>                        <Intersoft:UXMenuItem Header="De_lete" IsEnabled="False"/>                        <Intersoft:UXSeparator/>                        <Intersoft:UXMenuItem Header="Select _All" IsEnabled="False"/>                        <Intersoft:UXMenuItem Header="Time / _Date" IsEnabled="False"/>                     </Intersoft:UXMenuItem>                </Intersoft:DockPanel>            </Grid>        </Intersoft:UXWindow>    </Grid>

  8. Add a menu item called Format and sub-menu items for Bold and Italic as you repeat steps number 4-5.
    XAML
    Copy Code
     <Grid x:Name="LayoutRoot">    <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Edit.png" >        <Grid>            <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">                ...                <Intersoft:UXMenuItem Header="F_ormat">                    <Intersoft:UXMenuItem Header="Bold" Command="Commands:EditingCommands.Bold" IsCheckable="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/BoldHS.png"/>                    <Intersoft:UXMenuItem Header="Italic" Command="Commands:EditingCommands.Italic" IsCheckable="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/ItalicHS.png"/>                </Intersoft:UXMenuItem>            </Intersoft:DockPanel>        </Grid>    </Intersoft:UXWindow></Grid>

  9. Add the UXDockTray inside the DockPanel. Set the DockPanel.Dock property of UXDockTray into Top.
  10. Add the UXToolBar inside the UXDockTray.
  11. Add the UXToolGroup inside the UXToolBar.
  12. Add the UXToolBarButton inside the UXToolGroup. Set the following properties of UXToolBarButton as below.
    Properties Value
    DisplayMode Image
    Icon NewDocumentHS.png
    ToolTipService.ToolTip New Document

    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        ...
        <Intersoft:UXDockTray Name="uXDockTray1" Intersoft:DockPanel.Dock="Top">
            <Intersoft:UXToolBar Name="uXToolBar1">
                 <Intersoft:UXToolGroup Name="uXToolGroup1">
                 <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/NewDocumentHS.png" ToolTipService.ToolTip="New Document"/>
                 </Intersoft:UXToolGroup>
            </Intersoft:UXToolBar>
        </Intersoft:UXToolBar>
    </Intersoft:DockPanel>
  13. Add another UXToolBarButton for Open, Save, Print, Print Preview and Publish as you have created in the previous step.
    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        ...
        <Intersoft:UXDockTray Name="uXDockTray1" Intersoft:DockPanel.Dock="Top">
            <Intersoft:UXToolBar Name="uXToolBar1">
                 <Intersoft:UXToolGroup Name="uXToolGroup1">
                     <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/NewDocumentHS.png" ToolTipService.ToolTip="New Document"/>
                     <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/OpenFile.png" ToolTipService.ToolTip="Open Document"/>              <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/SaveHS.png" ToolTipService.ToolTip="Save"/>                 <Intersoft:UXSeparator/>                  <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PrintHS.png" ToolTipService.ToolTip="Print"/>               <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PrintPreviewHS.png" ToolTipService.ToolTip="Print Preview"/>                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PublishPlanHS.png" ToolTipService.ToolTip="Publish to Web"/>             </Intersoft:UXToolGroup>
            </Intersoft:UXToolBar>
        </Intersoft:UXToolBar>
    </Intersoft:DockPanel>

  14. Add another UXToolBar and UXToolBarButton for Undo, Redo, Cut, Copy, Paste, Bold and Italic as you repeat steps number 10-12.
    XAML
    Copy Code
     <Grid x:Name="LayoutRoot">        <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Edit.png" >            <Grid>                <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">                    ...                    <Intersoft:UXToolBar Name="uXToolBar2" ReturnOriginalFocus="True">                            <Intersoft:UXToolGroup>                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/Edit_UndoHS.png" ButtonType="SplitButton" ToolTipService.ToolTip="Undo" IsEnabled="False">                                    <Intersoft:UXMenuItem Header="Typing"/>                                    <Intersoft:UXMenuItem Header="Format Text"/>                                </Intersoft:UXToolBarButton>                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/Edit_RedoHS.png" ButtonType="SplitButton" ToolTipService.ToolTip="Redo" IsEnabled="False">                                    <Intersoft:UXMenuItem Header="Insert Picture"/>                                    <Intersoft:UXMenuItem Header="Typing"/>                                </Intersoft:UXToolBarButton>                                <Intersoft:UXSeparator/>                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CutHS.png" IsEnabled="False" ToolTipService.ToolTip="Cut"/>                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CopyHS.png" IsEnabled="False" ToolTipService.ToolTip="Copy"/>                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PasteHS.png" ToolTipService.ToolTip="Paste"/>                                <Intersoft:UXSeparator/>                                <Intersoft:UXToolBarButton IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/BoldHS.png" ToolTipService.ToolTip="Bold"/>                                <Intersoft:UXToolBarButton IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/ItalicHS.png" ToolTipService.ToolTip="Italic"/>                            </Intersoft:UXToolGroup>                        </Intersoft:UXToolBar>                    </Intersoft:UXDockTray>                </Intersoft:DockPanel>            </Grid>        </Intersoft:UXWindow>    </Grid>

  15. Add the RichTextBox inside the DockPanel. Set the Intersoft:ContextMenuService.ContextMenuName property into FormattingContextMenu and IsFillElement property of RichTextBox into True.
    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        ...
        <RichTextBox Name="richTextBox1" Intersoft:DockPanel.IsFillElement="True" Intersoft:ContextMenuService.ContextMenuName="FormattingContextMenu" />
    </Intersoft:DockPanel>

  16. Add the UXContextMenu inside the DockPanel.
  17. Add the UXMenuItem inside the UXContextMenu. Set the following properties of UXMenuItem as below.
    Properties Value
    Header Cut
    InputGestureText Ctrl+Shift+X
    IsEnabled False
    Icon CutHS.png
  18. Add another UXMenuItem for Copy, Paste, Bold and Italic as you have created in the previous step.
    XAML
    Copy Code
     <Grid x:Name="LayoutRoot">        <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Edit.png" >            <Grid>                <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">                    ...                    <Intersoft:UXContextMenu Name="uXContextMenu1">                        <Intersoft:UXMenuItem Header="Cut" InputGestureText="Ctrl+Shift+X" IsEnabled="False" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CutHS.png"/>                        <Intersoft:UXMenuItem Header="Copy" InputGestureText="Ctrl+Shift+C" IsEnabled="False" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/CopyHS.png"/>                        <Intersoft:UXMenuItem Header="Paste" InputGestureText="Ctrl+Shift+V" IsEnabled="False" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/PasteHS.png"/>                        <Intersoft:UXSeparator/>                        <Intersoft:UXMenuItem Header="Bold" IsCheckable="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/BoldHS.png"/>                        <Intersoft:UXMenuItem Header="Italic" IsCheckable="True" Icon="/RichEditorRoutedCommands;component/Assets/Images/Office/ItalicHS.png"/>                    </Intersoft:UXContextMenu>                </Intersoft:DockPanel>            </Grid>        </Intersoft:UXWindow>    </Grid>

  19. Set Intersoft:ContextMenuService.ContextMenuName property of RichTectBox into uXContextMenu1.
    C#
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
            <RichTextBox Name="richTextBox1" Intersoft:DockPanel.IsFillElement="True" Intersoft:ContextMenuService.ContextMenuName="uXContextMenu1" />
            ...
    </Intersoft:DockPanel>

Creating The Commanding Component

This section show how to create commands that going to be used your Rich Text Editor that you just created in the previous section.

To create the Application Command

  1. Create a class under the Command folder. Name it ApplicationCommands.cs.
  2. Add a new RoutedUICommand name it NewCommand.
    C#
    Copy Code
    public class ApplicationCommands
    {
        private static readonly RoutedUICommand NewCommand =
            new RoutedUICommand("New", "New", typeof(ApplicationCommands));
    
        public static RoutedUICommand New
        {
            get { return NewCommand; }
        }
    }
  3. Add two additional RoutedUICommand name them OpenCommand and SaveCommand.
    C#
    Copy Code
    public class ApplicationCommands
    {
        private static readonly RoutedUICommand OpenCommand =
            new RoutedUICommand("Open", "Open", typeof(ApplicationCommands));
    
        private static readonly RoutedUICommand SaveCommand =
            new RoutedUICommand("Save", "Save", typeof(ApplicationCommands));
    
        public static RoutedUICommand Save
        {
            get { return SaveCommand; }
        }
    
        public static RoutedUICommand Open
        {
            get { return OpenCommand; }
        }
    }
  4. Add a static constructor to register Shift+N input gesture for NewCommand and Shift+S input gesture for SaveCommand.
    C#
    Copy Code
    public class ApplicationCommands
    {
        static ApplicationCommands()
        {
            NewCommand.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control | ModifierKeys.Shift));
            SaveCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control | ModifierKeys.Shift));
        }
    
        public static void Initialize()
        {
            // empty initializer
        }
    }

To create the Editing Command

  1. Create a model class under the Command folder. Name it EditingCommands.cs.
  2. Add a new RoutedUICommand name it CutCommand.
    C#
    Copy Code
    public class EditingCommands
    {
        private static readonly RoutedUICommand CutCommand =
            new RoutedUICommand("Cut", "Cut", typeof(EditingCommands));
    
        public static RoutedUICommand Cut
        {
            get { return CutCommand; }
        }
    }
            
  3. Add four additional RoutedUICommand name them CopyCommand, PasteCommand, BoldCommand and ItalicCommand.
    C#
    Copy Code
    public class EditingCommands
    {
        private static readonly RoutedUICommand CopyCommand =
            new RoutedUICommand("Copy", "Copy", typeof(EditingCommands));
    
        private static readonly RoutedUICommand PasteCommand =
            new RoutedUICommand("Paste", "Paste", typeof(EditingCommands));
    
        private static readonly HybridRoutedCommand BoldCommand =
            new HybridRoutedCommand("Bold", "Bold", typeof(EditingCommands));
    
        private static readonly HybridRoutedCommand ItalicCommand =
            new HybridRoutedCommand("Italic", "Italic", typeof(EditingCommands));
    
        public static HybridRoutedCommand Italic
        {
            get { return ItalicCommand; }
        }
    
        public static HybridRoutedCommand Bold
        {
            get { return BoldCommand; }
        }
    
        public static RoutedUICommand Paste
        {
            get { return PasteCommand; }
        }
    
        public static RoutedUICommand Copy
        {
            get { return CopyCommand; }
        }
    }
  4. Add a static constructor to register Shift+X input gesture for CutCommand, Shift+C input gesture for CopyCommand, Shift+V input gesture for PasteCommand, Shift+B input gesture for BoldCommand and Shift+I input gesture for ItalicCommand.
    C#
    Copy Code
    static EditingCommands()
    {
        Cut.InputGestures.Add(new KeyGesture(Key.X, ModifierKeys.Control | ModifierKeys.Shift));
        Copy.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Control | ModifierKeys.Shift));
        Paste.InputGestures.Add(new KeyGesture(Key.V, ModifierKeys.Control | ModifierKeys.Shift));
        Bold.InputGestures.Add(new KeyGesture(Key.B, ModifierKeys.Control | ModifierKeys.Shift));
        Italic.InputGestures.Add(new KeyGesture(Key.I, ModifierKeys.Control | ModifierKeys.Shift));
    }
    
    public static void Initialize()
    {
        // empty initializer
    }

Bind the Command to the View

This section shows how to bind a command class use in as UXMenuItem and UXToolBarButton.

Bind the Command to the View

  1. In MainPage.xaml, add the following Commands namespace .
    XAML
    Copy Code
    <Intersoft:UXPage 
            ...
        xmlns:Command="clr-namespace:RichEditorRoutedCommand.Commands"
            ...>
  2. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with NewCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  3. Bind the ApplicationCommands.New to all component consist of New.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Intersoft:UXMenuItem Header="_New" Command="Commands:ApplicationCommands.New" InputGestureText="Ctrl+Shift+N" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/NewDocumentHS.png" />
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup Name="uXToolGroup1">
        <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.New" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/NewDocumentHS.png" ToolTipService.ToolTip="New Document"/>
        ...
    </Intersoft:UXToolGroup>
  4. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with OpenCommands name under UXMenuBar and UXToolBar.
  5. Bind the ApplicationCommands.Open to all component consist of Open.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">
        ...
        <Intersoft:UXMenuItem Header="_Open..." Command="Commands:ApplicationCommands.Open" Icon="/RichEditorRoutedCommand;component/Images/Office/OpenFile.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup Name="uXToolGroup1">
        ...
        <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.Open" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/OpenFile.png" ToolTipService.ToolTip="Open Document"/>
        ...
    </Intersoft:UXToolGroup>
  6. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with SaveCommands name under UXMenuBar and UXToolBar.
  7. Bind the ApplicationCommands.Save to all component consist of Save.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">
        ...
        <Intersoft:UXMenuItem Header="_Save" Command="Commands:ApplicationCommands.Save" Style="{StaticResource UXMenuItemStyle1}" InputGestureText="Ctrl+Shift+S" Icon="/Intersoft.ClientUI.Samples.Assets;component/Images/Office/SaveHS.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup Name="uXToolGroup1">
        ...
        <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.Save" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/SaveHS.png" ToolTipService.ToolTip="Save"/>
        ...
    </Intersoft:UXToolGroup>
  8. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with CutCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  9. Bind the EditingCommands.Cut to all component consist of Cut.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_Edit">
        ...
        <Intersoft:UXMenuItem Header="Cu_t" Command="Commands:EditingCommands.Cut" IsEnabled="False" InputGestureText="Ctrl+Shift+X" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup>
        ...
        <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Cut" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png" IsEnabled="False" ToolTipService.ToolTip="Cut"/>
        ...
    </Intersoft:UXToolGroup>

    XAML
    Copy Code
    <Intersoft:UXContextMenu Name="uXContextMenu1">
        <Intersoft:UXMenuItem Header="Cut" Command="Commands:EditingCommands.Cut" InputGestureText="Ctrl+Shift+X" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png"/>
        ...
    </Intersoft:UXContextMenu>
  10. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with CopyCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  11. Bind the EditingCommands.Copy to all component consist of Copy.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_Edit">
        ...
        <Intersoft:UXMenuItem Header="_Copy" Command="Commands:EditingCommands.Copy" IsEnabled="False" InputGestureText="Ctrl+Shift+C" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup>
        ...
        <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Copy" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png" IsEnabled="False" ToolTipService.ToolTip="Copy"/>
        ...
    </Intersoft:UXToolGroup>

    XAML
    Copy Code
    <Intersoft:UXContextMenu Name="uXContextMenu1">
        ...
        <Intersoft:UXMenuItem Header="Copy" Command="Commands:EditingCommands.Copy" InputGestureText="Ctrl+Shift+C" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png"/>
        ...
    </Intersoft:UXContextMenu>
  12. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with PasteCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  13. Bind the EditingCommands.Paste to all component consist of Paste.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="_Edit">
        ...
        <Intersoft:UXMenuItem Header="_Paste" Command="Commands:EditingCommands.Paste" IsEnabled="False" InputGestureText="Ctrl+Shift+V" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup>
        ...
        <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Paste" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png" ToolTipService.ToolTip="Paste"/>
        ...
    </Intersoft:UXToolGroup>

    XAML
    Copy Code
    <Intersoft:UXContextMenu Name="uXContextMenu1">
        ...
        <Intersoft:UXMenuItem Header="Paste" Command="Commands:EditingCommands.Paste" InputGestureText="Ctrl+Shift+V" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png"/>
        ...
    </Intersoft:UXContextMenu>
  14. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with BoldCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  15. Bind the EditingCommands.Bold to all component consist of Bold.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="F_ormat">
        <Intersoft:UXMenuItem Header="Bold" Command="Commands:EditingCommands.Bold" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png"/>
        ...
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup>
        ...
        <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Bold" IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png" ToolTipService.ToolTip="Bold"/>
        ...
    </Intersoft:UXToolGroup>

    XAML
    Copy Code
    <Intersoft:UXContextMenu Name="uXContextMenu1">
        ...
        <Intersoft:UXMenuItem Header="Bold" Command="Commands:EditingCommands.Bold" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png"/>
        ...
    </Intersoft:UXContextMenu>
  16. In MainPage.xaml, locate the UXMenuItem and UXToolBarButton related with ItalicCommands name under UXMenuBar, UXContextMenu and UXToolBar.
  17. Bind the EditingCommands.Italic to all component consist of Italic.
    XAML
    Copy Code
    <Intersoft:UXMenuItem Header="F_ormat">
        ...
        <Intersoft:UXMenuItem Header="Italic" Command="Commands:EditingCommands.Italic" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png"/>
    </Intersoft:UXMenuItem>

    XAML
    Copy Code
    <Intersoft:UXToolGroup>
        ...
        <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Italic" IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png" ToolTipService.ToolTip="Italic"/>
    </Intersoft:UXToolGroup>

    XAML
    Copy Code
    <Intersoft:UXContextMenu Name="uXContextMenu1">
        ...
        <Intersoft:UXMenuItem Header="Italic" Command="Commands:EditingCommands.Italic" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png"/>                    
    </Intersoft:UXContextMenu>
  18. Open MainPage.xaml.cs
  19. Initialize the ApplicationCommands and EditingCommands in the constructor.
    C#
    Copy Code
    public MainPage()
    {
        ApplicationCommands.Initialize();
        EditingCommands.Initialize();
    
        InitializeComponent();
    }
  20. Add the InitializeCommandBinding to register the handler.
    C#
    Copy Code
    private static void InitializeCommandBinding()
    {
        RoutedUICommand[] commands = new RoutedUICommand[] 
        {
            ApplicationCommands.New, ApplicationCommands.Open, ApplicationCommands.Save,
            EditingCommands.Cut, EditingCommands.Copy, EditingCommands.Paste,
            EditingCommands.Bold, EditingCommands.Italic
        };
    
        RoutedUICommand[] hybridCommands = new RoutedUICommand[] 
        {
            EditingCommands.Bold, EditingCommands.Italic
        };
    
        // register class-level command binding for RoutedUICommand
        foreach (RoutedUICommand command in commands)
        {
            CommandManager.RegisterClassCommandBinding(
                typeof(UXWindow),
                new CommandBinding(command, OnCommandExecuted, OnCanExecute));
        }
    }
  21. Create the OnCanExecute function handler to catch the Save, Cut, Bold and Italic command.
    C#
    Copy Code
    private static void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        MainPage page = Utility.FindVisualAncestor((DependencyObject)sender, typeof(UXPage)) as MainPage;
    
        // The e.CanExecute provides feedback to the associated caller whether the 
        // e.Command can be executed. If the value is false, the UI will be automatically disabled
        // thus enables consistent and reliable command interface.
    
        if (page == null)
        {
            e.CanExecute = false;
            return;
        }
    
        if (e.Command == ApplicationCommands.Save)
        {
            e.CanExecute = page.IsDirty;
        }
        else if (e.Command == EditingCommands.Cut || e.Command == EditingCommands.Copy)
        {
            e.CanExecute = page.richTextBox1.Selection != null && !string.IsNullOrEmpty(page.richTextBox1.Selection.Text);
        }
        else if (e.Command == EditingCommands.Bold || e.Command == EditingCommands.Italic)
        {
            e.CanExecute = page.richTextBox1.Selection != null && !string.IsNullOrEmpty(page.richTextBox1.Selection.Text);
        }
        else if (e.Command == EditingCommands.Paste)
        {
            e.CanExecute = page.richTextBox1.Selection != null && Clipboard.ContainsText();
        }
        else
        {
            e.CanExecute = true;
        }
    }
  22. Create the OnCommandExecuted function handler to catch the Save, Cut, Bold and Italic command which is execute after a requirement is fulfill on OnCanExecute function.
    C#
    Copy Code
    private static void OnCommandExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        MainPage page = Utility.FindVisualAncestor((DependencyObject)sender, typeof(UXPage)) as MainPage;
        RichTextBox rtb = page.richTextBox1;
    
        // When the e.Command is determined to be executable, the Executed handler will be invoked.
        // This function encapsulates the logic for each command in the sample.
    
        if (e.Command == ApplicationCommands.Save)
        {
            page.IsDirty = false;
        }
        else if (e.Command == ApplicationCommands.New)
        {
            rtb.SelectAll();
            rtb.Selection.Insert(new Paragraph());
            page.IsDirty = false;
        }
        else if (e.Command == EditingCommands.Cut)
        {
            Clipboard.SetText(rtb.Selection.Text);
            rtb.Selection.Insert(new Run());
        }
        else if (e.Command == EditingCommands.Copy)
        {
            Clipboard.SetText(rtb.Selection.Text);
        }
        else if (e.Command == EditingCommands.Paste)
        {
            if (!string.IsNullOrEmpty(Clipboard.GetText()))
                rtb.Selection.Insert(new Run() { Text = Clipboard.GetText() });
        }
        else if (e.Command == EditingCommands.Bold)
        {
            if ((FontWeight)rtb.Selection.GetPropertyValue(Run.FontWeightProperty) == FontWeights.Bold)
                rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal);
            else
                rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
        }
        else if (e.Command == EditingCommands.Italic)
        {
            if ((FontStyle)rtb.Selection.GetPropertyValue(Run.FontStyleProperty) == FontStyles.Italic)
                rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal);
            else
                rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic);
        }
    
        CommandManager.InvalidateRequerySuggested();
    }
  23. Add a static constructor of InitializeCommandBinding.
    C#
    Copy Code
    static MainPage()
    {
        InitializeCommandBinding();
    }

Invalidate the commands

This section shows how to invalidate the commands when the content of Rich Text Editor is changed or when the selection inside Rich Text Editor is changed.

To invalidate the commands.

  1. Open MainPage.xaml and locate RichTextBox control.
  2. Attach ContentChanged event handler and set the following validation inside the event handler.
    C#
    Copy Code
    private void RichTextBox_ContentChanged(object sender, ContentChangedEventArgs e)
    {
        if (!this.IsDirty)
        {
            this.IsDirty = true;
            CommandManager.InvalidateRequerySuggested();
        }
    }
  3. Attach SelectionChanged event handler and set the following code inside the event handler to invalidate the commands.
    C#
    Copy Code
    private void RichTextBox_SelectionChanged(object sender, RoutedEventArgs e)
    {
        CommandManager.InvalidateRequerySuggested();
    }
  4. Run the project. You will see the save icon is not active.
  5. Try to type a few words inside the RichTextBox and feel free to try all the commands you just made.
  6. The save icon is active then the RichTextEditor is considered dirty.
  7. The menu bar item also active when highlight the text.

Conclusion

In this walkthrough, you have learned how to create ClientUI MVVM project using project template, and create the classes and page based on the View and ViewModel pattern. You also learned how to bind the UXMenuBar, UXSeparator, UXDockTray, UXContextMenu, UXMenuItem, UXToolBar, and UXToolBarButton to a RoutedUICommand in the ViewModel which implement a notepad method inside the rich text editor.

Complete Code Listing

This section lists the complete code used in this walkthrough.


MainPage.xaml

XAML
Copy Code
<Intersoft:UXPage 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:Intersoft="http://intersoft.clientui.com/schemas"
    xmlns:Command="clr-namespace:RichEditorRoutedCommand.Commands"
        x:Class="RichEditorRoutedCommand.MainPage" 
        Title="MainPage Page"
        d:DesignWidth="640" d:DesignHeight="480">


    <Grid x:Name="LayoutRoot">
        <Intersoft:UXWindow Header="Intersoft Press - New Document" Name="uXWindow1" Width="480" Height="280" CanMaximize="False" CanMinimize="False" CanClose="False" IsActive="True" IsClientVisible="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Edit.png" >
            <Grid>
                <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
                    <Intersoft:UXMenuBar Name="uXMenuBar1" Intersoft:DockPanel.Dock="Top" AccessModifiers="Control, Alt">
                        <Intersoft:UXMenuItem Header="_File" HorizontalAlignment="Left" VerticalAlignment="Top">
                            <Intersoft:UXMenuItem Header="_New" Command="Commands:ApplicationCommands.New" InputGestureText="Ctrl+Shift+N" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/NewDocumentHS.png" />
                            <Intersoft:UXMenuItem Header="_Open..." Command="Commands:ApplicationCommands.Open" Icon="/RichEditorRoutedCommand;component/Images/Office/OpenFile.png"/>
                            <Intersoft:UXMenuItem Header="_Save" Command="Commands:ApplicationCommands.Save" InputGestureText="Ctrl+Shift+S" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/SaveHS.png"/>
                            <Intersoft:UXMenuItem Header="Save _As..."/>
                            <Intersoft:UXSeparator/>
                            <Intersoft:UXMenuItem Header="Page Set_up..."/>
                            <Intersoft:UXMenuItem Header="_Print..."/>
                            <Intersoft:UXSeparator/>
                            <Intersoft:UXMenuItem Header="E_xit"/>
                        </Intersoft:UXMenuItem>
                        <Intersoft:UXMenuItem Header="_Edit">
                            <Intersoft:UXMenuItem Header="_Undo" IsEnabled="False"/>
                            <Intersoft:UXSeparator/>
                            <Intersoft:UXMenuItem Header="Cu_t" Command="Commands:EditingCommands.Cut" IsEnabled="False" InputGestureText="Ctrl+Shift+X" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png"/>
                            <Intersoft:UXMenuItem Header="_Copy" Command="Commands:EditingCommands.Copy" IsEnabled="False" InputGestureText="Ctrl+Shift+C" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png"/>
                            <Intersoft:UXMenuItem Header="_Paste" Command="Commands:EditingCommands.Paste" IsEnabled="False" InputGestureText="Ctrl+Shift+V" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png"/>
                            <Intersoft:UXMenuItem Header="De_lete" IsEnabled="False"/>
                            <Intersoft:UXSeparator/>
                            <Intersoft:UXMenuItem Header="Select _All" IsEnabled="False"/>
                            <Intersoft:UXMenuItem Header="Time / _Date" IsEnabled="False"/>
                        </Intersoft:UXMenuItem>
                        <Intersoft:UXMenuItem Header="F_ormat">
                            <Intersoft:UXMenuItem Header="Bold" Command="Commands:EditingCommands.Bold" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png"/>
                            <Intersoft:UXMenuItem Header="Italic" Command="Commands:EditingCommands.Italic" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png"/>
                        </Intersoft:UXMenuItem>
                    </Intersoft:UXMenuBar>
                    <Intersoft:UXDockTray Name="uXDockTray1" Intersoft:DockPanel.Dock="Top">
                        <Intersoft:UXToolBar Name="uXToolBar1">
                            <Intersoft:UXToolGroup Name="uXToolGroup1">
                                <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.New" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/NewDocumentHS.png" ToolTipService.ToolTip="New Document"/>
                                <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.Open" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/OpenFile.png" ToolTipService.ToolTip="Open Document"/>
                                <Intersoft:UXToolBarButton Command="Commands:ApplicationCommands.Save" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/SaveHS.png" ToolTipService.ToolTip="Save"/>
                                <Intersoft:UXSeparator/>
                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PrintHS.png" ToolTipService.ToolTip="Print"/>
                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PrintPreviewHS.png" ToolTipService.ToolTip="Print Preview"/>
                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PublishPlanHS.png" ToolTipService.ToolTip="Publish to Web"/>
                            </Intersoft:UXToolGroup>
                        </Intersoft:UXToolBar>
                        <Intersoft:UXToolBar Name="uXToolBar2" ReturnOriginalFocus="True">
                            <Intersoft:UXToolGroup>
                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/Edit_UndoHS.png" ButtonType="SplitButton" ToolTipService.ToolTip="Undo" IsEnabled="False">
                                    <Intersoft:UXMenuItem Header="Typing"/>
                                    <Intersoft:UXMenuItem Header="Format Text"/>
                                </Intersoft:UXToolBarButton>
                                <Intersoft:UXToolBarButton DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/Edit_RedoHS.png" ButtonType="SplitButton" ToolTipService.ToolTip="Redo" IsEnabled="False">
                                    <Intersoft:UXMenuItem Header="Insert Picture"/>
                                    <Intersoft:UXMenuItem Header="Typing"/>
                                </Intersoft:UXToolBarButton>
                                <Intersoft:UXSeparator/>
                                <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Cut" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png" IsEnabled="False" ToolTipService.ToolTip="Cut"/>
                                <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Copy" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png" IsEnabled="False" ToolTipService.ToolTip="Copy"/>
                                <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Paste" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png" ToolTipService.ToolTip="Paste"/>
                                <Intersoft:UXSeparator/>
                                <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Bold" IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png" ToolTipService.ToolTip="Bold"/>
                                <Intersoft:UXToolBarButton Command="Commands:EditingCommands.Italic" IsToggleButton="True" DisplayMode="Image" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png" ToolTipService.ToolTip="Italic"/>
                            </Intersoft:UXToolGroup>
                        </Intersoft:UXToolBar>
                    </Intersoft:UXDockTray>
                    <RichTextBox Name="richTextBox1" Intersoft:DockPanel.IsFillElement="True" Intersoft:ContextMenuService.ContextMenuName="FormattingContextMenu" ContentChanged="RichTextBox_ContentChanged" SelectionChanged="RichTextBox_SelectionChanged" />
                    <Intersoft:UXContextMenu Name="uXContextMenu1">
                        <Intersoft:UXMenuItem Header="Cut" Command="Commands:EditingCommands.Cut" InputGestureText="Ctrl+Shift+X" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CutHS.png"/>
                        <Intersoft:UXMenuItem Header="Copy" Command="Commands:EditingCommands.Copy" InputGestureText="Ctrl+Shift+C" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/CopyHS.png"/>
                        <Intersoft:UXMenuItem Header="Paste" Command="Commands:EditingCommands.Paste" InputGestureText="Ctrl+Shift+V" IsEnabled="False" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/PasteHS.png"/>
                        <Intersoft:UXSeparator/>
                        <Intersoft:UXMenuItem Header="Bold" Command="Commands:EditingCommands.Bold" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/BoldHS.png"/>
                        <Intersoft:UXMenuItem Header="Italic" Command="Commands:EditingCommands.Italic" IsCheckable="True" Icon="/RichEditorRoutedCommand;component/Assets/Images/Office/ItalicHS.png"/>
                    </Intersoft:UXContextMenu>
                </Intersoft:DockPanel>
            </Grid>
        </Intersoft:UXWindow>
    </Grid>
</Intersoft:UXPage>

MainPage.xaml.cs

C#
Copy Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Intersoft.Client.UI.Navigation;
using RichEditorRoutedCommand.Commands;
using Intersoft.Client.Framework.Input;
using Intersoft.Client.Framework;
using Intersoft.Client.UI.Aqua.UXDesktop;

namespace RichEditorRoutedCommand
{
    public partial class MainPage : UXPage
    {
        public bool IsDirty { get; set; }

        public MainPage()
        {
            ApplicationCommands.Initialize();
            EditingCommands.Initialize();

            InitializeComponent();
        }

        static MainPage()
        {
            InitializeCommandBinding();
        }

        private static void InitializeCommandBinding()
        {
            RoutedUICommand[] commands = new RoutedUICommand[] 
            {
                ApplicationCommands.New, ApplicationCommands.Open, ApplicationCommands.Save,
                EditingCommands.Cut, EditingCommands.Copy, EditingCommands.Paste,
                EditingCommands.Bold, EditingCommands.Italic
            };

            RoutedUICommand[] hybridCommands = new RoutedUICommand[] 
            {
                EditingCommands.Bold, EditingCommands.Italic
            };

            // register class-level command binding for RoutedUICommand
            foreach (RoutedUICommand command in commands)
            {
                CommandManager.RegisterClassCommandBinding(
                    typeof(UXWindow),
                    new CommandBinding(command, OnCommandExecuted, OnCanExecute));
            }
        }

        private static void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            MainPage page = Utility.FindVisualAncestor((DependencyObject)sender, typeof(UXPage)) as MainPage;

            // The e.CanExecute provides feedback to the associated caller whether the 
            // e.Command can be executed. If the value is false, the UI will be automatically disabled
            // thus enables consistent and reliable command interface.

            if (page == null)
            {
                e.CanExecute = false;
                return;
            }

            if (e.Command == ApplicationCommands.Save)
            {
                e.CanExecute = page.IsDirty;
            }
            else if (e.Command == EditingCommands.Cut || e.Command == EditingCommands.Copy)
            {
                e.CanExecute = page.richTextBox1.Selection != null && !string.IsNullOrEmpty(page.richTextBox1.Selection.Text);
            }
            else if (e.Command == EditingCommands.Bold || e.Command == EditingCommands.Italic)
            {
                e.CanExecute = page.richTextBox1.Selection != null && !string.IsNullOrEmpty(page.richTextBox1.Selection.Text);
            }
            else if (e.Command == EditingCommands.Paste)
            {
                e.CanExecute = page.richTextBox1.Selection != null && Clipboard.ContainsText();
            }
            else
            {
                e.CanExecute = true;
            }
        }

        private static void OnCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            MainPage page = Utility.FindVisualAncestor((DependencyObject)sender, typeof(UXPage)) as MainPage;
            RichTextBox rtb = page.richTextBox1;

            // When the e.Command is determined to be executable, the Executed handler will be invoked.
            // This function encapsulates the logic for each command in the sample.

            if (e.Command == ApplicationCommands.Save)
            {
                page.IsDirty = false;
            }
            else if (e.Command == ApplicationCommands.New)
            {
                rtb.SelectAll();
                rtb.Selection.Insert(new Paragraph());
                page.IsDirty = false;
            }
            else if (e.Command == EditingCommands.Cut)
            {
                Clipboard.SetText(rtb.Selection.Text);
                rtb.Selection.Insert(new Run());
            }
            else if (e.Command == EditingCommands.Copy)
            {
                Clipboard.SetText(rtb.Selection.Text);
            }
            else if (e.Command == EditingCommands.Paste)
            {
                if (!string.IsNullOrEmpty(Clipboard.GetText()))
                    rtb.Selection.Insert(new Run() { Text = Clipboard.GetText() });
            }
            else if (e.Command == EditingCommands.Bold)
            {
                if ((FontWeight)rtb.Selection.GetPropertyValue(Run.FontWeightProperty) == FontWeights.Bold)
                    rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal);
                else
                    rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
            }
            else if (e.Command == EditingCommands.Italic)
            {
                if ((FontStyle)rtb.Selection.GetPropertyValue(Run.FontStyleProperty) == FontStyles.Italic)
                    rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal);
                else
                    rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic);
            }

            CommandManager.InvalidateRequerySuggested();
        }

        private void RichTextBox_ContentChanged(object sender, ContentChangedEventArgs e)
        {
            if (!this.IsDirty)
            {
                this.IsDirty = true;
                CommandManager.InvalidateRequerySuggested();
            }
        }

        private void RichTextBox_SelectionChanged(object sender, RoutedEventArgs e)
        {
            CommandManager.InvalidateRequerySuggested();
        }
    }
}

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Intersoft.Client.Framework.Input;

namespace RichEditorRoutedCommand.Commands
{
    public class ApplicationCommands
    {
        private static readonly RoutedUICommand NewCommand =
            new RoutedUICommand("New", "New", typeof(ApplicationCommands));

        private static readonly RoutedUICommand OpenCommand =
            new RoutedUICommand("Open", "Open", typeof(ApplicationCommands));

        private static readonly RoutedUICommand SaveCommand =
            new RoutedUICommand("Save", "Save", typeof(ApplicationCommands));

        public static RoutedUICommand Save
        {
            get { return SaveCommand; }
        }

        public static RoutedUICommand Open
        {
            get { return OpenCommand; }
        }

        public static RoutedUICommand New
        {
            get { return NewCommand; }
        }

        static ApplicationCommands()
        {
            NewCommand.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control | ModifierKeys.Shift));
            SaveCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control | ModifierKeys.Shift));
        }

        public static void Initialize()
        {
            // empty initializer
        }
    }
}

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Intersoft.Client.Framework.Input;

namespace RichEditorRoutedCommand.Commands
{
    public class EditingCommands
    {
        private static readonly RoutedUICommand CutCommand =
            new RoutedUICommand("Cut", "Cut", typeof(EditingCommands));

        private static readonly RoutedUICommand CopyCommand =
            new RoutedUICommand("Copy", "Copy", typeof(EditingCommands));

        private static readonly RoutedUICommand PasteCommand =
            new RoutedUICommand("Paste", "Paste", typeof(EditingCommands));

        private static readonly HybridRoutedCommand BoldCommand =
            new HybridRoutedCommand("Bold", "Bold", typeof(EditingCommands));

        private static readonly HybridRoutedCommand ItalicCommand =
            new HybridRoutedCommand("Italic", "Italic", typeof(EditingCommands));

        public static HybridRoutedCommand Italic
        {
            get { return ItalicCommand; }
        }

        public static HybridRoutedCommand Bold
        {
            get { return BoldCommand; }
        }

        public static RoutedUICommand Paste
        {
            get { return PasteCommand; }
        }

        public static RoutedUICommand Copy
        {
            get { return CopyCommand; }
        }

        public static RoutedUICommand Cut
        {
            get { return CutCommand; }
        }

        static EditingCommands()
        {
            Cut.InputGestures.Add(new KeyGesture(Key.X, ModifierKeys.Control | ModifierKeys.Shift));
            Copy.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Control | ModifierKeys.Shift));
            Paste.InputGestures.Add(new KeyGesture(Key.V, ModifierKeys.Control | ModifierKeys.Shift));
            Bold.InputGestures.Add(new KeyGesture(Key.B, ModifierKeys.Control | ModifierKeys.Shift));
            Italic.InputGestures.Add(new KeyGesture(Key.I, ModifierKeys.Control | ModifierKeys.Shift));
        }

        public static void Initialize()
        {
            // empty initializer
        }
    }
}
See Also

Concepts

Other Resources