Intersoft ClientUI Documentation
Walkthrough: Use Command Binding and Key Binding with MVVM Pattern

This walkthrough shows how to use command binding and key binding in a simple text editing application.

In this walkthrough, you perform the following tasks:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new Intersoft ClientUI Application Project

The first step is to create an Intersoft Application project using the provided Intersoft ClientUI Application project template.

To create the Intersoft 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.
  3. Add a reference to the Intersoft.ClientUI.Samples.Assets assembly, the assembly is available from the provided ClientUI sample.

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.

Creating The View

This section shows you how to create simple text editing application to demonstrate command binding and key binding.

To create the View

  1. Open MainPage.xaml.
  2. Add DockPanel to the LayoutRoot Grid.
  3. Add UXToolBar inside DockPanel.
    Set the DockPanel.Dock property to Top.
  4. Add UXToolGroup inside UXToolBar.
  5. Add UXToolBarButton inside UXToolGroup.
    Set the Content property to New, DisplayMode property to ContentAndImage and Icon to Assets/Images/NewDocumentHS.png
  6. Add another UXToolBarButton inside UXToolGroup.
    Set the Content property to New, DisplayMode property to ContentAndImage and Icon to Assets/Images/saveHS.png
  7. Add RichTextBox inside DockPanel.
    XAML
    Copy Code
    <Grid x:Name="LayoutRoot">
        <Intersoft:DockPanel FillChildMode="Custom">
            <Intersoft:CommandManager.CommandBindings>
                <Intersoft:CommandBindingCollection>
                    <Intersoft:CommandBinding Command="Commands:ApplicationCommands.New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
                    <Intersoft:CommandBinding Command="Commands:ApplicationCommands.Save" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
                </Intersoft:CommandBindingCollection>
            </Intersoft:CommandManager.CommandBindings>
            <Intersoft:CommandManager.InputBindings>
                <Intersoft:InputBindingCollection>
                    <Intersoft:KeyBinding Command="Commands:ApplicationCommands.New" Gesture="Ctrl+Shift+N"/>
                    <Intersoft:KeyBinding Command="Commands:ApplicationCommands.Save" Gesture="Ctrl+Shift+S"/>
                </Intersoft:InputBindingCollection>
            </Intersoft:CommandManager.InputBindings>
            <Intersoft:UXToolBar Intersoft:DockPanel.Dock="Top">
                <Intersoft:UXToolGroup>
                    <Intersoft:UXToolBarButton Content="New" DisplayMode="ContentAndImage" Icon="Assets/Images/NewDocumentHS.png" Command="Commands:ApplicationCommands.New"/>
                    <Intersoft:UXToolBarButton Content="Save" DisplayMode="ContentAndImage" Icon="Assets/Images/saveHS.png" Command="Commands:ApplicationCommands.Save"/>
                </Intersoft:UXToolGroup>
            </Intersoft:UXToolBar>
            <RichTextBox x:Name="RichTextBox1" Intersoft:DockPanel.Dock="Bottom" Intersoft:DockPanel.IsFillElement="True"/>
        </Intersoft:DockPanel>
    </Grid>

Creating the Commands

  1. In your project, create a new folder with name Commands.
  2. In Commands folder, create a new static class with name ApplicationCommands.
  3. In ApplicationCommands class, add the following command definitions.
    C#
    Copy Code
    public static class ApplicationCommands
    {
        private static readonly RoutedUICommand NewCommand =
            new RoutedUICommand("New", "New", typeof(ApplicationCommands));
    
        private static readonly RoutedUICommand SaveCommand =
            new RoutedUICommand("Save", "Save", typeof(ApplicationCommands));
    
        public static RoutedUICommand Save
        {
            get { return SaveCommand; }
        }
    
        public static RoutedUICommand New
        {
            get { return NewCommand; }
        }
    
        public static void Initialize()
        {
            // empty initializer
        }
    }

Binding the Commands to View

  1. Open MainPage.xaml page.
  2. Locate the DockPanel and create the CommandBinding as shown in the following code.
    XAML
    Copy Code
    <Intersoft:DockPanel FillChildMode="Custom">
        <Intersoft:CommandManager.CommandBindings>
            <Intersoft:CommandBindingCollection>
                <Intersoft:CommandBinding Command="Commands:ApplicationCommands.New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
                <Intersoft:CommandBinding Command="Commands:ApplicationCommands.Save" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
            </Intersoft:CommandBindingCollection>
        </Intersoft:CommandManager.CommandBindings>
        ....
        </Intersoft:DockPanel>
  3. Locate the DockPanel and create the KeyBinding as shown in the following code.
    The KeyBinding binds the commands such as New and Save command to specified key gesture, allowing you to use Ctrl + Shift + N to invoke New Command and Ctrl + Shift + S to invoke the Save Command.
    XAML
    Copy Code
    <Intersoft:DockPanel FillChildMode="Custom">
        ....
    
        <Intersoft:CommandManager.InputBindings>
            <Intersoft:InputBindingCollection>
                <Intersoft:KeyBinding Command="Commands:ApplicationCommands.New" Gesture="Ctrl+Shift+N"/>
                <Intersoft:KeyBinding Command="Commands:ApplicationCommands.Save" Gesture="Ctrl+Shift+S"/>
            </Intersoft:InputBindingCollection>
        </Intersoft:CommandManager.InputBindings>
        
       ....
    </Intersoft:DockPanel>
  4. Locate the UXToolBarButton and bind the Commands.
    XAML
    Copy Code
    <Intersoft:DockPanel FillChildMode="Custom">
        ....
            <Intersoft:UXToolBar Intersoft:DockPanel.Dock="Top">
            <Intersoft:UXToolGroup>
                <Intersoft:UXToolBarButton Content="New" DisplayMode="ContentAndImage" Icon="Assets/Images/NewDocumentHS.png" Command="Commands:ApplicationCommands.New"/>
                <Intersoft:UXToolBarButton Content="Save" DisplayMode="ContentAndImage" Icon="Assets/Images/saveHS.png" Command="Commands:ApplicationCommands.Save"/>
            </Intersoft:UXToolGroup>
        </Intersoft:UXToolBar>
        </Intersoft:DockPanel>
  5. Attach ContentChanged event handler for the RichTextBox.
    XAML
    Copy Code
    <Intersoft:DockPanel FillChildMode="Custom">
        ....
    
        <RichTextBox x:Name="RichTextBox1" Intersoft:DockPanel.Dock="Bottom" Intersoft:DockPanel.IsFillElement="True" ContentChanged="RichTextBox_ContentChanged"/>
    </Intersoft:DockPanel>

Handle the Commands

  1. Open MainPage.xaml.cs file.
  2. At the MainPage constructor, initialize the ApplicationCommands.
    C#
    Copy Code
    public MainPage()
    {
        ApplicationCommands.Initialize();
        InitializeComponent();
    }
  3. Create IsDirty property to indicates whether there are changes in the RichTextBox.
    C#
    Copy Code
    private bool _isDirty;
    private bool IsDirty
    {
        get { return this._isDirty; }
        set
        {
            if (this._isDirty != value)
            {
                this._isDirty = value;
                CommandManager.InvalidateRequerySuggested();
            }
        }
    }
  4. Create event handlers for CanExecute and Execute event that you declare in the previous section.
    C#
    Copy Code
    private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        if (e.Command == ApplicationCommands.New)
        {
            e.CanExecute = true;
        }
        else if (e.Command == ApplicationCommands.Save)
        {
            e.CanExecute = this.IsDirty;
        }            
    }
    
    private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        if (e.Command == ApplicationCommands.New)
        {
            this.RichTextBox1.SelectAll();
            this.RichTextBox1.Selection.Insert(new Paragraph());
        }
        else if (e.Command == ApplicationCommands.Save)
        {
            this.IsDirty = false;
            MessageBox.Show("Your document is saved!");
        }   
    }
  5. Create the RichTextBox_ContentChanged method to handle the ContentChanged event of the RichTextBox control.
    C#
    Copy Code
    private void RichTextBox_ContentChanged(object sender, ContentChangedEventArgs e)
    {            
        if (!this.IsDirty)
        {
            this.IsDirty = true;
        }
    }
  6. Run the project.

Testing the Commands

  1. You will see that the Save button is disabled at start up.
  2. Try type something in the RichTextBox and you will see the Save button become enabled.
  3. Press Ctrl + Shift + S to execute the save command.

 

Conclusion

In this walkthrough, you have learned how to create commands and also create the command bindings and the key bindings declaratively in XAML. You have also learned how to handle each commands in the code behind.

Complete Code Listing

This section lists the complete code used in this walkthrough.

ApplicationCommands.cs

C#
Copy Code
using Intersoft.Client.Framework.Input;

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

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

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

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

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

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:Commands="clr-namespace:ClientUIApplication1.Commands"
    x:Class="ClientUIApplication1.MainPage" 
    Title="MainPage Page"
    d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">
        <Intersoft:DockPanel FillChildMode="Custom">
            <Intersoft:CommandManager.CommandBindings>
                <Intersoft:CommandBindingCollection>
                    <Intersoft:CommandBinding Command="Commands:ApplicationCommands.New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
                    <Intersoft:CommandBinding Command="Commands:ApplicationCommands.Save" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
                </Intersoft:CommandBindingCollection>
            </Intersoft:CommandManager.CommandBindings>
            <Intersoft:CommandManager.InputBindings>
                <Intersoft:InputBindingCollection>
                    <Intersoft:KeyBinding Command="Commands:ApplicationCommands.New" Gesture="Ctrl+Shift+N"/>
                    <Intersoft:KeyBinding Command="Commands:ApplicationCommands.Save" Gesture="Ctrl+Shift+S"/>
                </Intersoft:InputBindingCollection>
            </Intersoft:CommandManager.InputBindings>
            <Intersoft:UXToolBar Intersoft:DockPanel.Dock="Top">
                <Intersoft:UXToolGroup>
                    <Intersoft:UXToolBarButton Content="New" DisplayMode="ContentAndImage" Icon="Assets/Images/NewDocumentHS.png" Command="Commands:ApplicationCommands.New"/>
                    <Intersoft:UXToolBarButton Content="Save" DisplayMode="ContentAndImage" Icon="Assets/Images/saveHS.png" Command="Commands:ApplicationCommands.Save"/>
                </Intersoft:UXToolGroup>
            </Intersoft:UXToolBar>
            <RichTextBox x:Name="RichTextBox1" Intersoft:DockPanel.Dock="Bottom" Intersoft:DockPanel.IsFillElement="True" ContentChanged="RichTextBox_ContentChanged"/>
        </Intersoft:DockPanel>
    </Grid>
</Intersoft:UXPage>

MainPage.xaml.cs

C#
Copy Code
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using ClientUIApplication1.Commands;
using Intersoft.Client.Framework.Input;
using Intersoft.Client.UI.Navigation;

namespace ClientUIApplication1
{
    public partial class MainPage : UXPage
    {
        private bool _isDirty;
        private bool IsDirty
        {
            get { return this._isDirty; }
            set
            {
                if (this._isDirty != value)
                {
                    this._isDirty = value;
                    CommandManager.InvalidateRequerySuggested();
                }
            }
        }


        public MainPage()
        {
            ApplicationCommands.Initialize();
            InitializeComponent();
        }
        
        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {

        }

        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.New)
            {
                e.CanExecute = true;
            }
            else if (e.Command == ApplicationCommands.Save)
            {
                e.CanExecute = this.IsDirty;
            }            
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.New)
            {
                this.RichTextBox1.SelectAll();
                this.RichTextBox1.Selection.Insert(new Paragraph());
            }
            else if (e.Command == ApplicationCommands.Save)
            {
                this.IsDirty = false;
                MessageBox.Show("Your document is saved!");
            }   
        }

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

Concepts

Other Resources