RSS

Category Archives: .NET WPF

Providing simple collaboration support for your diagramming tools with WCF services.


Notes: This article assumes you are already familiar with WCF services or studying them.

Several months ago I’ve posted simple draft project for a small diagramming tool. Though I didn’t intend it to be a tool or starter kit it is still the most visited post among all other more interesting things ;) As I’ve been playing with WCF and wanted some simple environment for testing some ideas I remembered about old CTP project and found it was quite a good playground for my experiments. So this article will be using the reviewed and edited version of the project mentioned in the old article.

I’d also recommend you visiting the Code Project to see the wonderful samples by Marcus. I’ve dared to take his toolbox and tool item implementation for my article samples :)

What is the key changes made since the previous sample:

1. Simple MVC pattern implementation sample

The classes introducing the pattern are:

DiagramView: WPF canvas hosting the shapes and connection lines

DiagramController: Simply the controller

DiagramModel: Data model hosting the business objects (entities) that are not related to presentation layer.

As my intention was processing business objects rather that shapes and controls I’ve decided to perform a dummy bridging between raw "DiagramEntity" classes and their UI representation.

I’ve also simplified event system between Model, Controller and View based on Action<DiagramEntity> delegates for clarity purposes. Model is capable only of storing the entities, adding them and removing. In this implementation the View is also responsible for instantiating the Collaboration Client that will be described later on.

2. Unity Application Block

I’ve reduced the influence of the service bus for many parts of the application in favor to Unity Application Block. That made my life much easier.

3. Toolbox

As I moved on for using a simple toolbox I’ve eliminated the shape tools and shape creators that were rudimentary parts of Factory design pattern. But left the connection creator tools with a simple Strategy pattern implementation just for educational purposes.

4. Extensions and IExtensibleObject<T> interface

In this article I’ve described some ideas for extending Canvas panels by means of IExtensibleObject<T> interface taken from WCF. I’ve decided it would be fair enough reusing this stuff to show that it’s working fine. The Canvas (View) is extended with Selection and Drag functionality that can be simple switched off if required.

5. Aero theme by default and many minor improvements…

Here’s how it looks like

image

 

Basic collaboration support using WCF service

My intention was giving some sketches for how it could be implemented and some raw material for starting to play with. So I’ll be concentrating on it omitting thread safeties, error checking and the stuff like that for clarity purposes. Guess it would be much easier extending the sources based raw skeleton implementation.

Business objects

Entities

As I’ve mentioned the entities my service will be operating on are not related to presentation layer so it won’t be aware of WPF and the stuff like that. It will be the View responsibility turning them into the visuals and applying different styles and templates. Meanwhile we need at least some basic UI related information be passed like positioning coordinates so this is what UIEntity class serves for. I’ll be playing with three entities named "DataEntity", "SystemEntity" and "UserEntity" that will be turned later on to the appropriate shapes at client side. This provides nice presentation flexibility allowing different clients using specific visuals and styles though following one remote model.

Remote Model and Remote Callbacks

I’ve chosen the Duplex WCF service for the sample that requires implementing a callback contract also. For more details on duplex services better refer to MSDN library as it might take long time for me describing theory that is already perfectly presented ;)

This is how the remote model might look like:

using System.ServiceModel;

namespace Collaboration.Contracts
{
  [ServiceContract(
    Name = "RemoteModel",
    Namespace = "http://dvuyka.spaces.live.com/diagramming/types",
    CallbackContract = typeof(IRemoteModelCallback),
    SessionMode = SessionMode.Required)]
  [ServiceKnownType(typeof(UserEntity))]
  [ServiceKnownType(typeof(DataEntity))]
  [ServiceKnownType(typeof(SystemEntity))]
  public interface IRemoteModel
  {
    [OperationContract(IsOneWay = true)]
    void AddEntity(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void RemoveEntity(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void Connect();
  }
}

Due to serialization purposes our model should be aware of all the inheritances that might take part in the collaboration process. I’ve declared them as "known" to the service being described by this interface. Our remote model will also provide Adding and Removing capabilities like the "local" tool’s model and subscription to service via the Connect method.

The callback contract might look like the following:

using System.ServiceModel;

namespace Collaboration.Contracts
{
  public interface IRemoteModelCallback
  {
    [OperationContract(IsOneWay = true)]
    void OnEntityAdded(DiagramEntity entity);

    [OperationContract(IsOneWay = true)]
    void OnEntityRemoved(DiagramEntity entity);
  }
}

It means that remote model (or simply service) will be raising "OnEntityAdded" and "OnEntityRemoved" events for all the subscribers providing them with the entities to be immediately added to the local model and so presented with the View.

Wiring up the "local" model

At the client side we are creating a simple wrapper delegating remote model events to the local model like the following

using Collaboration.Contracts;

namespace HomeDiagramming.Collaboration
{  
  public sealed class RemoteModelCallback : IRemoteModelCallback
  {
    public DiagramModel LocalModel { get; private set; }

    public RemoteModelCallback(DiagramModel localModel)
    {
      this.LocalModel = localModel;
    }

    #region IRemoteModelCallback Members

    public void OnEntityAdded(DiagramEntity entity)
    {
      this.LocalModel.AddEntity(entity);
    }

    public void OnEntityRemoved(DiagramEntity entity)
    {
      this.LocalModel.RemoveEntity(entity);
    }

    #endregion
  }
}

So each time the service will be publishing "OnEntityAdded" or "OnEntityRemoved" events to it’s subscribers the event execution will be delegated to the underlying local model by calling it’s appropriate members.

The client connecting our remote model will be as simple as possible:

using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Collaboration.Contracts;

namespace HomeDiagramming.Collaboration
{
  [DebuggerStepThrough]
  public class RemoteModelClient : DuplexClientBase<IRemoteModel>, IRemoteModel
  {
    public RemoteModelClient(InstanceContext callbackInstance) :
      base(callbackInstance)
    {
    }

    public RemoteModelClient(InstanceContext callbackInstance, Binding binding, 
EndpointAddress address)
      : base(callbackInstance, binding, address)
    {      
    }

    #region IRemoteModel Members

    public void AddEntity(DiagramEntity entity)
    {
      base.Channel.AddEntity(entity);
    }

    public void RemoveEntity(DiagramEntity entity)
    {
      base.Channel.RemoveEntity(entity);
    }

    public void Connect()
    {
      base.Channel.Connect();
    }

    #endregion
  }
}

During creation of the View that instantiates the Controller we can initialize our remote controller in the following way

InstanceContext context = new InstanceContext(new RemoteModelCallback(this.Controller.Model));
NetTcpBinding binding = new NetTcpBinding();
EndpointAddress address = new EndpointAddress("net.tcp://localhost:8080/RemoteModel");    
remoteModel = new RemoteModelClient(context, binding, address);
remoteModel.Connect();

Remote model skeleton

And finally here comes the raw skeleton for the remote model

using System;
using System.Collections.Generic;
using System.ServiceModel;
using Collaboration.Contracts;

namespace Collaboration.Service
{
  [ServiceBehavior(
    InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode=ConcurrencyMode.Multiple)]
  public class RemoteModel : IRemoteModel
  {
    // TODO: should be the thread-safe collections
    private List<DiagramEntity> entities = new List<DiagramEntity>();
    private List<IRemoteModelCallback> callbacks = new List<IRemoteModelCallback>();

    #region IRemoteModel Members

    public void AddEntity(DiagramEntity entity)
    {
      // TODO: should be performed in a thread-safe manner and fully async
      Console.WriteLine("Adding entity :" + entity.Name);
      lock (entities)
      {
        this.entities.Add(entity);        
      }

      Console.WriteLine("Entity added. Total count: " + entities.Count);
      IRemoteModelCallback callback = GetCallback();      
      foreach (IRemoteModelCallback c in callbacks)
        if (c != callback)
          c.OnEntityAdded(entity);
    }

    public void RemoveEntity(DiagramEntity entity)
    {
      // TODO: should be performed in a thread-safe manner      
    }

    public void Connect()
    {
      IRemoteModelCallback callback = GetCallback();
      if (!callbacks.Contains(callback))
      {        
        callbacks.Add(callback);
        Console.WriteLine("User connected. Total count: " + callbacks.Count);
      }
    }

    private IRemoteModelCallback GetCallback()
    {
      return OperationContext.Current.GetCallbackChannel<IRemoteModelCallback>();
    }

    #endregion
  }
}

As you can see it is a Singleton service with Multiple ConcurrencyMode. Each connected client will be registered within the subscribers collection (callbacks). Each model change causes all the subscribers to be notified.

In my implementation each client immediately applies changes to the Model and View. Guess the rest of functionality might depend on your ideas.

The source code for the article can be  found here:

Possible issues:

If you encounter exceptions related to connection try changing the ports for your endpoints. On some machines localhost:8080 may be not allowed. Change it to localhost:8000 ("App.config" for server and "DiagramView.cs" for client) or whatever port is available free and doesn’t violate your firewall policy.

Notes: In order to build solution you’ll need the release version of Unity Application Block. Solution is configured to run both service and demo application at a time. Open the binaries folder for demo application and run several instances of application in order to ensure all clients receive notifications and create shapes at a time.

 
1 Comment

Posted by on April 23, 2008 in .NET WPF

 

Injecting Xaml with Unity Application Block using Markup Extensions. Part 4.


Delegating Routed Events (Event Handlers).

This is a continued research dedicated to Unity Application Block.

For more details please refer to the following posts

Part 1. Basic injection of custom user controls.

Part 2. Injection of standard WPF controls. Setting properties for injected controls.

Part 3. Attached dependency properties. Binding delegation. Code behind support.

To be honest I didn’t expect myself splitting the topic across 4 posts. And I didn’t plan writing the 4rth one until I collect a batch of features to be presented. But after yesterdays playing with injections I decided that I have to implement and share with one more helpful feature as event delegation. This will be a good ending for the series until I collect feedbacks and ideas to be able to continue it.

What’s the purpose injecting WPF (or 3rd party) controls without specifying event handlers from my current page like for the common controls? This was the question I wanted to answer myself yesterday. As I’ve started the way injection extension behaved itself in a maximum intuitive manner I definitely wanted to set event handlers in the common manner too (meaning intellisense, generation of new handler within the current page, etc).

I tried to follow the "Setters" approach for properties and make the standard "EventSetter" class suite my needs but encountered some difficulties with it’s implementation. So the easiest and quickest solution was following the "PropertySetter" approach and introduce another placeholder for the event.

Again I’ve decided to change the naming :) Everything being wrapped by the custom classes were suffixed with the "Injector". PropertySetter became PropertyInjector, BindingSetter became BindingInjector and so new event setter became EventInjector accordingly. This was mainly done to follow one scheme and not to affect existing extensions’ names.

So here’s what I wanted to have as a result

image

Unity Control extension provides additional collection for storing ready to delegation event handlers. You have the possibility of specifying appropriate routed event and assign or generate event handler for it like you would do for the common Button control.

EventInjector itself is represented by the following holder:

public class EventInjector
{
  public RoutedEvent Event { get; set; }
  public event RoutedEventHandler Handler;

  public bool IsValid
  {
    get { return Event != null && Handler != null; }
  }

  public void AssignTo(FrameworkElement element)
  {
    if (IsValid)
      element.AddHandler(Event, Handler);
  }
}

Unity Control extension keeps the list of assigned EventInjector objects until the underlying UI control is resolved within the Unity Container. After that all event handlers are assigned for the control. Rather simple approach that might require enhancements in your implementations. Anyway does it’s job :)

You can specify a chain of "Button.Click" events or specify a set of different routed events, everything will be delegated to the underlying control until control has the routed event being assigned.

Guess this single and small extension finishes the basic feature set that is required to move your controls to another abstraction level and provide possibilities for hot changing/patching of your UI elements via the application configuration file.

Source code for the article

 
Leave a comment

Posted by on April 4, 2008 in .NET WPF

 

Injecting Xaml with Unity Application Block using Markup Extensions. Part 3.


Attached dependency properties. Bindings. Code behind support.

This is a continued research dedicated to Unity Application Block.

For more details please refer to the following posts

Part 1. Basic injection of custom user controls.

Part 2. Injection of standard WPF controls. Setting properties for injected controls.

Introduction

After having played by myself with injector markup extension implementation described in the previous article I found out a lot of limitations that could be easily introduced.

I used "PropertySetter" wrapper for delegating properties to the injected elements based on dependency property descriptors taken from string representation of property names. This restricted me either from setting common non-dependency properties or supporting Attached Properties. Though good for panel layouts injected controls for example couldn’t be properly positioned for the Canvas.

Another thing I wanted to have is ability for delegating dependency property bindings to injected control. This could be also a very interesting task as I found no ways of declaring Binding markup extension within the Xaml that are having deferred processing/execution.

Third feature I was looking for is correct referencing injected controls from the code behind. I wanted to be fully transparent delegating the names of UnityControl extensions to the injected controls so having possibilities of addressing them via .FindName(…) method

As the mission was successfully accomplished I’m putting the most interesting details here…

Prerequisites

As we are going to deal with Bindings we need getting one level upper in the type mapping as UIElement doesn’t support bindings. We will be using FrameworkElement for binding purposes. This requirement slightly impacts the Application Configuration File we are using for Container initialization. Instead of UIElement contract we have to declare FrameworkElement alias and map all the controls to it.

Here’s the sample:

<typeAlias alias="FrameworkElement" type="System.Windows.FrameworkElement, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

The rest of the control aliases remain the same.

The container types are mapped to this alias accordingly like the following:

<types>
  <type type="FrameworkElement" mapTo="Button" name="UnityButton"/>
  <type type="FrameworkElement" mapTo="TabControl" name="UnityTabControl"/>
  <type type="FrameworkElement" mapTo="TextBox" name="UnityTextBox"/>
  <type type="FrameworkElement" mapTo="ListBox" name="UnityListBox"/>
</types>

(Attached) Dependency Properties Support

While it is more convenient maintaining dependency properties using DependencyPropertyDescriptor, common "plain" properties are maintained using Reflection – PropertyInfo. I’ve decided to decouple these two worlds to have capability of deciding which approach is more appropriate in this or that situation.

I’m using the standard Setter class for targeting (attached)dependency properties as this class may seem more intuitive than custom control implementation. Setter class also deals with DependencyProperty object and so provides native way of controlling the values defined. This is how our injection declaration looks like:

<this:UnityControl Name="btn1" Container="defaultProvider" Dependency="UnityButton">
    <this:UnityControl.Setters>
        <Setter Property="FrameworkElement.Height" Value="50"/>
        <Setter Property="Canvas.Left" Value="100"/>
        <Setter Property="Canvas.Top" Value="100"/>
    </this:UnityControl.Setters>
    
    <this:UnityControl.Properties>
        <this:PropertySetter Property="Content" 
                             Value="{StaticResource resourceString}"/>                    
    </this:UnityControl.Properties>
</this:UnityControl>

As you can see UnityControl extension now contains a collection property "Setters" accepting objects of "Setter" type. "Setters" collection is processed using dependency property descriptors only.

"Properties" collection property accepts objects of "PropertySetter" type and is processed using PropertyInfo. This means that PropertySetter can be also defined for a common dependency property, but it doesn’t support attached dependency properties. So as you can see this modification provides backwards compatibility for the samples from the previous article.

Main purpose of using standard Setter class as I’ve said earlier is restricting users from defining plain strings for property names. For the markup be valid each setter must have any valid dependency property defined. Thus PropertySetter accepts string based values and is more error prone. Each approach has it’s advantages and disadvantages so it’s up to you deciding which and at what time to use.

Dependency Property Binding Delegation

As you can understand the markup extensions’ inner world from the previous articles it’s quite difficult to control standard Binding markup extension. And guess it’s nearly impossible (at least for current version of WPF) subclassing it or providing deferred initialization/execution mechanisms. This means we cannot use default Binding extension for delegation purposes as we cannot control it’s life cycle.

The most easiest way was to follow the "PropertySetter" approach and introducing "BindingSetter" class for wrapping most basic functionality for establishing a binding.

Here’s the source code for such a wrapper:

public sealed class BindingSetter
{
  public DependencyProperty Property { get; set; }
  public string ElementName { get; set; }
  public DependencyProperty Path { get; set; }
  public BindingMode Mode { get; set; }
  public IValueConverter Converter { get; set; }
  public object ConverterParameter { get; set; }
  public object FallbackValue { get; set; }
}

So the main task for UnityControl extension will be enumerating the setters defined and constructing appropriate Bindings for the resolved FrameworkElement.

Let’s take a Canvas panel and inject the TextBox based control by "UnityTextBox" name like the following:

<this:UnityControl Name="txtBox" 
                   Container="defaultProvider" 
                   Dependency="UnityTextBox" 
                   Content="Default">
    <this:UnityControl.Setters>
        <Setter Property="FrameworkElement.Width" Value="100"/>
    </this:UnityControl.Setters>
</this:UnityControl>

Next let’s inject a Button based control named "UnityButton":

<this:UnityControl Name="btn1" Container="defaultProvider" Dependency="UnityButton">
    <this:UnityControl.Setters>
        <Setter Property="FrameworkElement.Height" Value="50"/>
        <Setter Property="Canvas.Left" Value="100"/>
        <Setter Property="Canvas.Top" Value="100"/>
    </this:UnityControl.Setters>
    
    <this:UnityControl.Bindings>
        <this:BindingSetter 
            Property="ContentControl.Content" 
            ElementName="txtBox" 
            Path="TextBox.Text" 
            Mode="OneWay"
            Converter="{StaticResource testConverter}"
            ConverterParameter="[{0}]"/>
    </this:UnityControl.Bindings>
</this:UnityControl>

Button will be have a Height value of 100 and will be positioned at (100,100) point at the Canvas. Also we define a one way binding between Button.Content and TextBox.Text. Also for demonstration purposes I’ve configured simple value converter and converter parameter. Converter is formatting the input string according to parameter template.

image

UnityControl markup extension takes the element resolved via Unity Container and configures the Binding manually. Of course it is not fully functional and there’s no MultiBinding support (guess this will require another enhancement for future articles) but demonstrates that it is possible to do.

 

Code Behind Support

It is obvious that you won’t get all the required functionality by declaring xaml only. It logically comes out that next thing you might require is accessing the injected elements from code behind. This is also required for Binding establishment. You might have already noticed the "Name" attribute definition in the samples above.

<this:UnityControl Name="txtBox" 
                   Container="defaultProvider" 
                   Dependency="UnityTextBox" 
                   Content="Default">
    <this:UnityControl.Setters>
        <Setter Property="FrameworkElement.Width" Value="100"/>
    </this:UnityControl.Setters>
</this:UnityControl>

Note that my implementation of Name property is not the same as x:Name markup extension. Name property is used in this case for delegating x:Name for the control being injected using the Unity Container. It is not mandatory so you can omit it if not required.

Upon injection UnityControl extension takes the Namescope of the parent container and registers the newly resolved element within it’s scope using the Name property if it was defined.

This brings out that the following Window.Loaded event handler be fully functional:

void Window1_Loaded(object sender, RoutedEventArgs e)
{      
  // Get the control injected with the UnityControl extension
  TextBox txtBox = canvas.FindName("txtBox") as TextBox;
}  

So this means that declaring injection in the Xaml you still have access to the element being injected and not taking care about the injector markup itself.

The source code for the article can be found here.

 
Leave a comment

Posted by on April 2, 2008 in .NET WPF

 

Injecting Xaml with Unity Application Block using Markup Extensions. Part 2.


Notes: This article assumes that you are familiar or started playing with a Unity Application Block. I won’t dwell on describing it’s architecture or manuals so please refer to the link mentioned for more details.

Introduction

In the previous article I’ve described how user custom controls can be injected into Xaml markup without code behind operations using custom Markup Extensions. I’ve mentioned that there might be more easy way of introducing common WPF controls without any need for subclassing. So my second article will cover this very situation.

Aliases and Type Mapping

Similar to declaring contract interfaces and mapping all the required types to single content you can have no predefined contract. Dealing with UI controls common UIElement class may serve perfectly well as a contract. Especially if you noticed that my UnityReference markup extension was dealing with UIElement objects mainly.

So UIElement alias declaration within our "App.config" file can be the following

<typeAlias alias="UIElement" type="System.Windows.UIElement, PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

Similar to the line above you are able to declare aliases for any set of controls required for your use in the Unity Container. Here’s what I’ll be playing with later on:

<typeAlias alias="Button" type="System.Windows.Controls.Button, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<typeAlias alias="TabControl" type="System.Windows.Controls.TabControl, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<typeAlias alias="TextBox" type="System.Windows.Controls.TextBox, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<typeAlias alias="ListBox" type="System.Windows.Controls.ListBox, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

As you can see I’ve just declared four standard controls.

Container definition is extremely simple

<container name="containerOne">
        <types>
          <type type="UIElement" mapTo="Button" name="UnityButton"/>
          <type type="UIElement" mapTo="TabControl" name="UnityTabControl"/>
          <type type="UIElement" mapTo="TextBox" name="UnityTextBox"/>
          <type type="UIElement" mapTo="ListBox" name="UnityListBox"/>
        </types>
      </container>

All the controls are mapped under base UIElement type. Each control name is prefixed with a "Unity*" to bring more clearance in the markup (this is just for testing purposes and you can provide any name you want).

Container Provider and Configuration  Markup Extension

Both Container Provider and Configuration extension remains unchanged so you can refer to the previous post or source code for more detailed information.

UnityControl Markup Extension

Here comes the most important part. UnityControl markup extension is based on the previous "UnityReference" one though extended with a set of more efficient facilities.

Support for property setters

As this extension is being transformed into UIElement it is obvious that we might want defining some properties not covered with initialization phase or whatever. For this very purpose I’ve introduced dedicated collection of my custom "PropertySetter" classes. PropertySetter contains only two properties: "Property(string)" and "Value(object)"

Here’s the basic example what I’m talking about

<this:UnityControl Container="defaultProvider" Dependency="UnityListBox">                
    <this:UnityControl.Properties>
        <this:PropertySetter Property="Background" Value="Wheat"/>
        <this:PropertySetter Property="Height" Value="100"/>
        <this:PropertySetter Property="ItemsSource">
            <this:PropertySetter.Value>
                <x:Array Type="sys:String">
                    <sys:String>Hello</sys:String>
                    <sys:String>World</sys:String>
                </x:Array>
            </this:PropertySetter.Value>
        </this:PropertySetter>
    </this:UnityControl.Properties>
</this:UnityControl>

Here I’ve injected some UI control named "UnityListBox", specified Background and Height. Also I’ve provided a list of strings to be applied as an ItemsSource.

<this:UnityControl Container="defaultProvider" Dependency="UnityTabControl">
    <this:UnityControl.Properties>
        <this:PropertySetter Property="Height" Value="100"/>
        <this:PropertySetter Property="ItemsSource">
            <this:PropertySetter.Value>
                <x:Array Type="TabItem">
                    <TabItem Header="Page1"/>
                    <TabItem Header="Page2"/>
                </x:Array>
            </this:PropertySetter.Value>
        </this:PropertySetter>
    </this:UnityControl.Properties>
</this:UnityControl>

Here I’ve injected a "UnityTabControl" element and predefined two pages of TabItem type.

The property/value conversion procedure is rather dummy and the subject to change but you are able configuring some properties and getting the basic idea. Note that I’ve supported only Dependency Properties.

Default Content Property Support

Next thing I wanted a lot is specifying the Content of UIElement in the common WPF manner without declaring any additional tags. Most of the standard controls have some properties marked with the ContentPropertyAttribute pointing to the property that will be defined when specific declaration is omitted.

For this case I’ve also implemented additional property "Content" for my markup extension and delegated it’s value to the control being injected with the container.

Here’s the sample:

<this:UnityControl Container="defaultProvider" Dependency="UnityButton">
    <this:UnityControl.Properties>                    
        <this:PropertySetter Property="Height" Value="50"/>
    </this:UnityControl.Properties>                
    <Image Source="Images/data.png" Width="32" Height="32" Stretch="Uniform"/>                
</this:UnityControl>

In this sample I’m injecting "UnityButton" element defining it’s Height property value. Also pay attention to the Image control declaration as a default content. This will be delegated to the button’s content after injection. Omitting the properties you can use the following declaration either:

<this:UnityControl Container="defaultProvider" Dependency="UnityButton">
    <Image Source="Images/data.png" Width="32" Height="32" Stretch="Uniform"/>                
</this:UnityControl>

The content can be also defined using the following markup

<this:UnityControl Container="defaultProvider" Dependency="UnityTextBox" Content="Default text"/>

In this sample I’m injecting the "UnityTextBox" control providing the Content as "Default text" string. As TextBox defines "TextProperty" dependency property as a default content I’ve defined the TextBox text here.

image

Conclusion

This approach may help you dynamically configuring your UI without rebuilding main application. Changing the type mapping or introducing new aliases you bring more power and extensibility. Any time any control can be patched or changed to completely new implementation.

Note: I’ve rebuild Unity targeting .net 3.5 framework. Binaries can be found in the "binaries" folder of the project.

Source code for the article

 
Leave a comment

Posted by on April 1, 2008 in .NET WPF

 

Injecting Xaml with Unity Application Block using Markup Extensions


Notes: This article assumes that you are familiar or started playing with a Unity Application Block. I won’t dwell on describing it’s architecture or manuals so please refer to the link mentioned for more details.

Today I’ve got another drop of Unity Application Block and decided to play with it in the scope of WPF to see what ideas might appear and how flexible Unity may be dealing with Xaml. For testing purposes I’ve decided to get Unity Container being referenced totally within the markup without code behind usage. Additionally I wanted to get some dummy UI elements built up by the container and injected into the page. It took me approximately 2 hours of playing and I must say I was quite satisfied with the results.

I’ll be giving just the pure idea to be elaborated without any fancy visual stuff. That’s up to you guys to get anything worth usable from it.

Common Unity Container can be configured in two ways. It is either manual configuration and initialization at code behind or using configuration file ("App.config" or "Web.config"). Of course for keeping experiment clear I’ve chosen the latter one – application configuration.

Here’s a simple snippet that can be found in the documentation file

<?xml version="1.0" encoding="utf-8" ?>
<
configuration>
  <
configSections>
    <
section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
                 Culture=neutral, PublicKeyToken=31bf3856ad364e35
" />
  </
configSections>
 
  <
unity>
    <
typeAliases/>
   
    <
containers>
      <
container name="containerOne">
        <
types/>
      </
container>
    </
containers>
   
  </
unity>
</
configuration>

So we declare common Unity section called "unity" and one container called "containerOne". Type aliases and container types will be described later on.

Next step is bringing a container to the upper level from code behind to markup. We need something declared within the page that can be referenced to from the other elements. It can be achieved either by declaring a static resource or introducing some bridge control wrapping your Container. I’ve chosen the latter one because it might give me possibilities easy accessing my container either from xaml or code behind depending on situation and complexity of requirements.

Unity Container Provider

Simple initialization of Unity Container from code behind looks like the following

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
  (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers["containerOne"].Configure(container);

So we need to know the section name and container name to create and configure properly our container. This means that theoretically we could have some element on the page like following:

<ContainerProvider Name="defaultProvider" Section="unity" Container="containerOne"/>

Such control doesn’t require any UI representation and can serve like data provider similar to Windows Forms Designer age ;)

To save your time for future enhancements there’s quite a good reason providing additional facility that will populate any control with a Unity Container (if appropriate property is supported by control) and so giving you possibility integrating the logic in more complex layouts and implementations.

This is where Markup Extensions come.

Unity Configuration Extension (UnityConfiguration.cs)

using System;
using System.Configuration;
using System.Windows.Markup;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace UnityTesting1
{
  [MarkupExtensionReturnType(typeof(IUnityContainer))]
  public class UnityConfiguration : MarkupExtension
  {
    #region Properties
    [ConstructorArgument("section")]
    public string Section { get; set; }

    [ConstructorArgument("container")]
    public string Container { get; set; } 
    #endregion

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
      IUnityContainer container = new UnityContainer();
      UnityConfigurationSection section = 
        (UnityConfigurationSection)ConfigurationManager.GetSection(Section);
      section.Containers[Container].Configure(container);
      return container;
    }

    #region ctors
    public UnityConfiguration()
    {
    }

    public UnityConfiguration(string section, string container)
    {
      this.Section = section;
      this.Container = container;
    } 
    #endregion
  }
}

Here I’ve introduced a very simple markup extension that will provide our elements with a Unity container taken from application configuration. It has two properties: "Section" for section name and "Container" for referencing some required container within the configuration section.

For getting more really good details on markup extensions you may refer to Rob Relyea’s blog

So assuming our container provider has a dedicated property for storing a container it can now be declared like the following:

<ContainerProvider
      x:Name="defaultProvider"
      Container="{UnityConfiguration Section=unity, Container=containerOne}"/>

Guess it’s a more convenient way using markup extension in this case because as you’ve might understood that it can be applied to any object that holds IUnityContainer child as a property.

Using extension above our container holder source becomes extremely simple:

Container Provider Contract (IContainerProvider.cs)

public interface IContainerProvider
{
  IUnityContainer Container { get; }
}

This is mainly for future extensibility and flexibility.

Container Provider (ContanerProvider.cs)

public class ContainerProvider : FrameworkElement, IContainerProvider
{    
  public IUnityContainer Container { get; set; }
}

As you can see we are having more lookless stub I think than fully featured control. You can get rid of it or introduce new features at any time.

Just to ensure injection methods works fine and to have a stab for future implementations I’ve introduced a dummy service called "ContentResolver" that it to be used as a singleton and take part in the entities buildup process. It won’t do a lot but demonstrate the possible usage for flexible initialization of our UI elements.

Content Resolver Contract (IContractResolver.cs)

public interface IContentResolver
  {
    string GetName();
  }

Content Resolver (ContentResolver.cs)

public class ContentResolver : IContentResolver
  {
    #region IPersonResolver Members

    public string GetName()
    {
      //return Guid.NewGuid().ToString("B");
      return DateTime.Now.ToLongTimeString();
    }

    #endregion
  }

Our following controls will be taking the data via this service. Again reminding that this is absolutely optional and can be skipped.

Next step is providing some UI elements we will build up via our Unity container. I’ll give two samples: Image and ListBox controls just to catch the main idea. Our sample controls will be exposing IContent contract for flexibility purposes

Content Contract (IContent.cs)

public interface IContent
{
}

I will use it mainly for identification and generalization purposes so the contract doesn’t have any members.

Image Content (ImageContent.cs)

public class ImageContent : Control, IContent
{
  public string ImagePath { get; set; }
  public string Text { get; set; }

  static ImageContent()
  {
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageContent), 
      new FrameworkPropertyMetadata(typeof(ImageContent)));
  }
  
  [InjectionMethod]
  public void Initialize(IContentResolver resolver)
  {      
    this.Text = resolver.GetName();
    this.ImagePath = "Images/gear.png";
  }
}

Our simple control has two properties "ImagePath" and "Text". Normally they should be Dependency Properties but I’ve simplified it to have a compact view of general info ;) It has a customized template (see attached sources for more details).

Also you can see the injected method that provides basic initialization of a control. Here you normally insert more efficient stuff required for controls and taken from external singleton based (in my implementation) service.

ListBox Content (ListBoxContent.cs)

public class ListBoxContent : ListBox, IContent
{
  public ListBoxContent()
  {
    this.Items.Add("One");
    this.Items.Add("Two");
    this.Items.Add("Three");
    this.Items.Add("Four");
    this.Items.Add("Five");
  }
}

Next control represents a common ListBox. It doesn’t require any initialization injection and has no overridden templates.

Actually you can avoid creating wrapper classes for standard controls and this is what normally you will do in a real-life development. As this will require using Activator class and dynamic Type instantiation I’ve decided to move the simple way to keep the code and configuration file more understandable. But keep in mind that it’s absolutely possible and there’s no problems implementing that for you in future.

Configuration file (App.config)

Here’s how our final configuration file that we’ll be using across the sample application:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
              type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
                 Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>

  <unity>

    <typeAliases>

      <typeAlias alias="singleton" 
                 type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, 
                 Microsoft.Practices.Unity" />
      
      <typeAlias alias="IContentResolver" 
                 type="UnityTesting1.IContentResolver, UnityTesting1"/>
      <typeAlias alias="ContentResolver" 
                 type="UnityTesting1.ContentResolver, UnityTesting1"/>
      
      <typeAlias alias="IContent" 
                 type="UnityTesting1.IContent, UnityTesting1"/>
      <typeAlias alias="ImageContent" 
                 type="UnityTesting1.ImageContent, UnityTesting1"/>
      <typeAlias alias="ListBoxContent" 
                 type="UnityTesting1.ListBoxContent, UnityTesting1"/>
      
    </typeAliases>

    <containers>
      <container name="containerOne">
        <types>

          <type type="IContentResolver" mapTo="ContentResolver">
            <lifetime type="singleton" />
          </type>

          <type type="IContent" mapTo="ImageContent" name="UnityImage"/>
          <type type="IContent" mapTo="ListBoxContent" name="UnityList"/>
          
        </types>
        </container>
    </containers>

  </unity>

</configuration>

I’ve created all required aliases and filled container with appropriate types. Our Image and ListBox content will be accessed using "UnityImage" and "UnityList" names.

So if we were using the code behind approach we would resolve our "UnityList" using the following line:

IContent content = container.Resolve<IContent>("UnityList");

This returns as an object of ListBoxContent type that is actually a subclass of ListBox and so UIElement that can be easily added to the visual tree of a panel, canvas or whatever.

Analyzing content creation you can see that generally for creating our control we need initialized Unity container and name of the element to be resolved. This can be theoretically put to xaml in the following way:

<SomeElement Container="defaultProvider" Dependency="UnityList"/>

We have already discussed container provider element so how exactly we can reference it in the code and what else should be created that can cover all our content controls? We definitely need another markup extension that will give us all the required possibilities…

Unity Reference Markup Extension (UnityReference.cs)

[MarkupExtensionReturnType(typeof(UIElement))]
public class UnityReference : MarkupExtension
{
  #region Properties
  [ConstructorArgument("container")]
  public string Container { get; set; }

  [ConstructorArgument("dependency")]
  public string Dependency { get; set; } 
  #endregion

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    IProvideValueTarget ipvt = 
      (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
    FrameworkElement fe = ipvt.TargetObject as FrameworkElement;
    FrameworkContentElement fce = ipvt.TargetObject as FrameworkContentElement;

    if (fe != null)
    {        
      IContainerProvider containerProvider = 
        fe.FindName(Container) as IContainerProvider;
      if (containerProvider == null)
        throw new Exception("IContainerProvider not found!");

      return containerProvider.Container.Resolve<IContent>(this.Dependency);
    }
    else if (fce != null)
    {
      IContainerProvider containerProvider = 
        fce.FindName(Container) as IContainerProvider;
      if (containerProvider == null)
        throw new Exception("IContainerProvider not found!");

      return containerProvider.Container.Resolve<IContent>(this.Dependency);
    }
    else
      throw new Exception("Container " + Container + " cannot be resolved!");
  }

  #region ctors
  public UnityReference()
  {
  }

  public UnityReference(string container, string dependency)
  {
    this.Container = container;
    this.Dependency = dependency;
  } 
  #endregion
}

Here we’ve introduced a unified approach for presenting our Unity based controls using a simple (hope so) markup extension. Next it becomes possible using the following declaration in a xaml:

<UnityReference Container="defaultProvider" Dependency="UnityList"/>

As markup extension turns into the UIElement resolved within the "defaultProvider" container holder we get a fully functional ListBoxContent control at the end of processing.

Finally here comes the sample application that can be constructed of such blocks

<Window x:Class="UnityTesting1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:this="clr-namespace:UnityTesting1"
    Title="Window1" Height="600" Width="800">    
    
    <DockPanel LastChildFill="True">
        
        <this:ContainerProvider 
            x:Name="defaultProvider" 
            Container="{this:UnityConfiguration 
                Section=unity, 
                Container=containerOne}"/>
        
        <StackPanel DockPanel.Dock="Left" 
                    Width="200" 
                    Background="AliceBlue">            
            <this:UnityReference 
                Container="defaultProvider" 
                Dependency="UnityList"/>
        </StackPanel>
        <Canvas x:Name="canvas">            
            <Button Width="100" 
                    Content="{this:UnityReference 
                        Container=defaultProvider, 
                        Dependency=UnityImage}"/>
        </Canvas>
    </DockPanel>    
    
</Window>

image

The source code for the article can be found here

 
2 Comments

Posted by on March 31, 2008 in .NET WPF

 

Make your WPF controls fully extensible using WCF IExtensibleObject pattern (.net 3.0)


 

Two days ago while reading MSDN documentation details on WCF’s NetDataContractSerializer I found a reference to the IExtensibleObject interface from "System.ServiceModel.dll". There were no details concerning what for the sample serializable object was exposing it as it was out of the sample scope. So I tried to figure out the purpose of this interface and how it can be reused in my applications when not dealing with Communication Foundation. Of course as you might have noticed the 2008 MSDN library contains almost no developer-readable information and the situation gets worse and worse ;) , the Googling also gave me nothing except various annoying reprints of MSDN articles. It took me two days of investigations to figure out how much power this pattern can bring to common applications.

IExtensibleObject<T>

Exposing this interface "Enable an object to participate in custom behavior, such as registering for events, or watching state transitions [...] For example, if you are implementing a TreeNode class and want to allow external code to add annotations and methods to some instances of TreeNode, you can have TreeNode implement IExtensibleObject<TreeNode>. This enables code that uses TreeNode to add objects that implement IExtensibleObject<TreeNode> to the Extensions collection." (MSDN). And four confusing samples from Windows Communication foundation… ;)

So starting implementation of our extensible class…

public class Person: IExtensibleObject<Person>
{
  public string Name { get; set; }

  public Person()
  {
    Extensions = new ExtensionCollection<Person>(this);     
    Name = "Default Name";     
  }

  #region IExtensibleObject<Person> Members

  public IExtensionCollection<Person> Extensions { get; private set; }
  #endregion
}

Actually I like those Persons and Dogs samples all over the MSDN so continued the tradition :)

IExtensibleObject<Person> requires you implementing only the strong-typed "Extensions" collection. We don’t require any extreme logic so using the default out-of-box ExtensionCollection. For testing and debugging purposes I also define the name of our person to something meaningful :)

IExtensionCollection<T>

Won’t be rewriting the obvious information, guess you should better take a look the original article. It is supposed to hold the extensions for the extensible object. Default ExtensionCollection class provides you the possibility of fetching the result sets from it entries directly according the type you are acquiring. For more details see Find<E> and FindAll<E> details for the collection.

IExtension<T>

This is what your "Extensions" collection expects you to provide ;) Each your extension should expose this interface having the same <T> as the object being extended. Guess it might be more easy to get the idea from the sample below

public class PersonExtension : IExtension<Person>
  {
    #region IExtension<Person> Members

    public void Attach(Person owner)
    {
      Console.WriteLine("Attaching to owner called: " + owner.Name);
    }

    public void Detach(Person owner)
    {
      Console.WriteLine("Detaching from owner called: " + owner.Name);
    }

    #endregion
  }

IExtension<T> exposing needs two methods to be implemented by the author of the extension class: Attach and Detach. Very easy and the main things needed to extend the owner. Before each extension is added to the Extensions collection the Attach method is called to provide extension with possibility to initialize itself (cache the parent instance, attach events, change properties, whatever you need). Each time the extension is removed from the collection the Detach method is called so the extension class finalize itself, release resources, detach event handlers, etc. Each time for both steps extension gets it’s owner in order.

In this sample I won’t be doing anything except sending a notification with a current owner name just to be sure the code is correct.

Putting it all together

Person p = new Person() { Name = "Denis Vuyka" };
p.Extensions.Add(new PersonExtension());

You create an instance of the Person class, set the name property and add a new instance of the PersonExtension to it. Upon adding the extension you will see the "Attaching to owner…" message in your VS Output window. So the code is working.

 

Extending WPF UI elements

Another good sample would be showing some UI element being extended. I’ve chosen a Canvas but you are free to choose anything you need actually.

public class ExtensibleCanvas : Canvas, IExtensibleObject<ExtensibleCanvas>
{
  public ExtensibleCanvas()
    : base()
  {
    this.Background = Brushes.Transparent;
    this.Extensions = new ExtensionCollection<ExtensibleCanvas>(this);
  }
  
  #region IExtensibleObject<ExtensibleCanvas> Members

  public IExtensionCollection<ExtensibleCanvas> Extensions { get; private set; }

  #endregion
}

Again as in the previous sample we create our custom class inheriting IExtensibleObject and a Canvas control. As I will be playing with Mouse events I set the "Background" property of the canvas to "Transparent" to have a valid mouse responses. Also again we initialize our Extensions collection providing ourselves as an owner of the collection.

As I want just simply react to the MouseLeftButtonDown event of the ExtensibleCanvas the code sample for the extension will be the following

public class CanvasExtension : IExtension<ExtensibleCanvas>
{    
  #region IExtension<ExtensibleCanvas> Members

  public void Attach(ExtensibleCanvas owner)
  {
    owner.MouseLeftButtonDown += new MouseButtonEventHandler(owner_MouseLeftButtonDown);
  }

  void owner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  {
    MessageBox.Show("Extension report: MouseLeftButtonDown event hooked!");
  }

  public void Detach(ExtensibleCanvas owner)
  {
    owner.MouseLeftButtonDown -= owner_MouseLeftButtonDown;
  }

  #endregion
}

During attach phase we wire up the MouseLeftButtonDown event with our own extension handler and release it during the detach phase. Each time the left button of the mouse if down we simply display a message box.

Putting it all together

Here’s the source for our sample window

<Window x:Class="CanvasExtensions.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ext="clr-namespace:CanvasExtensions"
    Title="Window1" Height="300" Width="300">
    <ext:ExtensibleCanvas x:Name="myExtensibleCanvas">
        
    </ext:ExtensibleCanvas>
</Window>

Here we just simply registered our local namespace and declared the ExtensibleCanvas instance called "myExtensibleCanvas".

Here’s the source code for our sample window

using System;
using System.Windows;

namespace CanvasExtensions
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();

      // Testing extending the UI (Canvas extensions)
      myExtensibleCanvas.Extensions.Add(new CanvasExtension());
    }
  }
}

Just add a new instance of Canvas extension, run application and click somewhere on the canvas. You’ll get the message box with some text in it.

 

Extending dependency objects

As I immediately started to fill the power of this pattern (thanks to Microsoft guys who implemented it :) ) I’ve decided to gain more control over the dependency objects that they can give me within their public properties and events. I’ve decided that there’s a cases when "wise" extension could have the need integrating deeper into the property system of the owner object thus I won’t have the possibility or time extending the owner to support "OnChanged" events.

So this example will show you how to extend the dependency objects (so read "all the UI controls present in WPF also" :) ) that don’t want to tell anyone of their properties changes.

Let’s extend our Person class to be dependency object having "Name" property as a dependency one:

public class DoPerson : DependencyObject, IExtensibleObject<DoPerson>
{
  public string Name
  {
    get { return (string)GetValue(NameProperty); }
    set { SetValue(NameProperty, value); }
  }

  // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
  public static readonly DependencyProperty NameProperty =
      DependencyProperty.Register("Name", typeof(string), typeof(DoPerson), new UIPropertyMetadata("Default Name"));
      
  public DoPerson()
  {
    Extensions = new ExtensionCollection<DoPerson>(this);
  }

  #region IExtensibleObject<DoPerson> Members

  public IExtensionCollection<DoPerson> Extensions { get; private set; }

  #endregion
}

Now we have DependencyObject Person or DoPerson for short. Let’s imagine someone else had written this class and I have no possibility of tracking whether the name of DoPerson object has changed indeed. Thanks for WPF dependency system this is also possible via the "DependencyPropertyDescriptor". Let’s imagine your extension wants to know when the Name property of it’s owner is changed and want to slightly modify resulting value according to some internal rules.

Here’s how will look like the updated version of extension called DoPersonExtension. For educational purposes and code clearance I didn’t implement any checks and safe casting, hope you’ll understand that right

public class DoPersonExtension : IExtension<DoPerson>
{    
  DependencyPropertyDescriptor dpDes;
  bool NamePropertyLock = false;

  #region IExtension<DoPerson> Members

  public void Attach(DoPerson owner)
  {
    dpDes = DependencyPropertyDescriptor.FromProperty(DoPerson.NameProperty, typeof(DoPerson));
    dpDes.AddValueChanged(owner, HookOwnerNameChanged);
  }

  public void Detach(DoPerson owner)
  {
    dpDes.RemoveValueChanged(owner, HookOwnerNameChanged);
  }

  #endregion

  private void HookOwnerNameChanged(object sender, EventArgs e)
  {
    // avoid entering endless loop here
    if (NamePropertyLock) return;
          
    NamePropertyLock = true;

    ((DoPerson)sender).Name += "(hooked by extension)";

    NamePropertyLock = false;
  }
}

What a hell the extension is doing here… :)

It extracts the DependencyPropertyDescriptor from the DoPersonClass for his dependency property Name and attaches it’s own handler for value changed event that is raised regardless the DoPerson notifies about or not ;) As now both the extension and owner classes are dealing with the same property it is obvious that some locking should be implemented not to bring application into endless loop when changing the Name and so avoiding overflow exceptions.

Upon detachment from the owner extensions collections DoPersonExtension clears it’s own garbage by removing the event handler for the property descriptor.

The testing lines for the sample above could be similar to following

// Testing extending of DependencyObject hooking the change of properties
// when no change events are supported withing the object
DoPerson doPerson = new DoPerson();
doPerson.Extensions.Add(new DoPersonExtension());

Console.WriteLine("Setting name: Denis Vuyka");
doPerson.Name = "Denis Vuyka";

Console.WriteLine("Current name: " + doPerson.Name);

I create a DoPerson instance and add the appropriate extension to it. Then I set the value of the "Name" property to my own name :) and instantly put it in the Output window. As our extension hooked the Name setter we have the following message as a result:

"Current name: Denis Vuyka (hooked by extension)"

This is the simplest sample and the rest depends on your imagination.

Finalizing my article I’d like to admit that this pattern perfectly fits into MVC pattern as you can simply change the control flow vice versa. The extended object itself can iterate through the extension collection and call appropriate methods and do something he needs to do. So it means the Controller can also get the power unleashed :)

Have a nice coding…

 

 
Leave a comment

Posted by on January 15, 2008 in .NET WPF

 

Upcoming WPF Diagramming framework


 

As Francois Vanderseypen has disclosed some info in his post Mindmapping layout in WPF I’ve also decided to make a small announcement towards that :)

We joined our forces on the way implementing full "WPF replacement" for Netron 3 due to a small mindmapping application that resides on the top of the it. For the last couple of months it takes all my spare time but I must admit it really brings a lot of pleasure working with WPF and .net 3.5 in this way :) We try to get the most of MVC and MS service buses approaches to perform scalable and highly extensible diagramming framework.

While you can see the layout details and screenshots here I’ll single out some additional features that might be of interest to developer audience.

Stress on lightweight MS service bus architecture close to MS designer re-hosting approaches so to be very intuitive for those guys familiar with Windows Forms and Workflow designers re-hosting. Some common services like unlimited Undo/Redo, Zooming/Panning, Drag/Drag to scroll, Single and Multiselection, Movement/Resizing, exporting content to different formats including images and XPS. Variety of Line connectors and different types of Shapes.

Stress on maximizing the extensibility of the core designer functionality. Nearly each part of the functionality can be plugged in/changed/disabled by the single developer according to the needs. Flexible service model.

Different drawing surfaces for diagram types like trees, mindmaps, flowcharts etc.

Even writing this very small list of features requires me a lot of investigations towards the native WPF features and possibilities of implementation this or that feature. Due to the lack of documentation and good samples for WPF (especially in diagramming and drawing) I have to surf with Reflector and google a lot :) This also gives me some additional and rare material worth placing into separate blog posts concerning WPF itself. I’ll try to find some free hours in the nearest future for that :)

Of course we are only on the way preparing some world-ready app demos but the progress is very stable ;)

Meanwhile I would advice the people really interested in diagramming and WPF solutions stay on the line for other news within "The Orbifold" and my blog. Thanks for your attention.

 
Leave a comment

Posted by on January 10, 2008 in .NET WPF

 

WPF. Simplify your life with Linq extension methods, Canvas and Visual Tree helpers.


This article dwells on .net 3.5 and Visual C# 2008 Express Edition.

Up to current moment I’ve been using the Canvas element very much with the diagramming stuff that I described earlier. As you implement something similar you definitely come across inconvenience using the standard Children collection property. There’s very little changes that you will be using only UIElement objects. For example you have some shapes exposing different interfaces, something like ISelectable, IDraggable or anything else. Additionally you have a variety of visual connections and drawings inheriting Paths, Geometry or Figures.  So each time you come across type casting and code longer that it could be ;)

 

1. Extending base classes

When you need three or more core functions for manipulating canvas children and don’t have the possibility of inheriting/implementing additional stuff for your own classes there’s a good opportunity of extending the Canvas class itself using a couple of Linq extension methods for that.

using System.Windows;
using System.Windows.Controls;

namespace UsefulExtensions.Extensions
{
  public static class CanvasExtension
  {
    public static void AddChild<T>(this Canvas canvas, T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement != null && !canvas.Children.Contains(uiElement))
        canvas.Children.Add(uiElement);
    }

    public static void RemoveChild<T>(this Canvas canvas, T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement != null && canvas.Children.Contains(uiElement))
        canvas.Children.Remove(uiElement);
    }

    public static void InsertChild<T>(this Canvas canvas, int index, T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement != null && !canvas.Children.Contains(uiElement))
        canvas.Children.Insert(index, uiElement);
    }
  }
}

Of course you should carefully read the documentation towards the extension methods at least at your local VS MSDN library. There’s a good explanation how it works and where and when to use these features.

Similar to "System.Linq" whenever you declare the namespace "UserfulExtensions.Extensions" (or your own namespace name) you get the additional methods for all the Canvas based classes.

image

 

The best thing I like using generics is the transparency of T provided. That’s a really great feature having the possibility to omit the T declaration within the generic method. Of course sometimes it may bring to small problems but in most cases helps you a lot.

Having shapes exposing for example IDraggable and ISelectable interfaces you don’t need to explicitly define the type as T when calling generic methods.

The method call will look like following:

myCanvas.AddChild(myShape1);

myCanvas.AddChild(myShape2)

The T will be automatically resolved by the type/interface of the parameter provided. You can actually pass anything you to the method but that’s not the fact the element will be added to the Canvas. As you have seen earlier the extension methods require the element be at least of UIElement type to perform an action, so the next thing will also compile but won’t be executed at runtime.

myCanvas.AddChild(0)

myCanvas.AddChild(new Point(10,10))

As I’ve already said I like the generics feature of resolving the <T> and I think it’s really useful.

 

2. Implementing helper classes

2.1. Canvas helper

Helper classes is the thing each developer implement very often. When you use the canvas child maintenance using the methods above you come to conclusion that the standard "Canvas.GetLeft" or "Canvas.GetTop" are not enough flexible for you as they also deal with UIElement objects while you require some generics approach for that. It’s very easy to implement a static helper class to correct that.

Here’s a quick snippet I use often

CanvasHelper.cs

using System;
using System.Windows;
using System.Windows.Controls;

namespace UsefulExtensions.Helpers
{
  public static class CanvasHelper
  {
    public static double GetLeft<T>(T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");
      return (double)uiElement.GetValue(Canvas.LeftProperty);
    }

    public static double GetTop<T>(T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");
      return (double)uiElement.GetValue(Canvas.TopProperty);
    }

    public static Point GetPosition<T>(T element)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");

      return new Point(
        (double)uiElement.GetValue(Canvas.LeftProperty),
        (double)uiElement.GetValue(Canvas.TopProperty));
    }

    public static void SetLeft<T>(T element, double length)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");
      uiElement.SetValue(Canvas.LeftProperty, length);
    }

    public static void SetTop<T>(T element, double length)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");
      uiElement.SetValue(Canvas.TopProperty, length);
    }

    public static void SetPosition<T>(T element, Point value)
    {
      UIElement uiElement = element as UIElement;
      if (uiElement == null)
        throw new ArgumentNullException("element");
      uiElement.SetValue(Canvas.LeftProperty, value.X);
      uiElement.SetValue(Canvas.TopProperty, value.Y);
    }
  }
}

I didn’t provide any supplementary information for the sources above because I hope it’s quite self-describing. As static Canvas members "GetLeft" and "GetTop" deal with the attached dependency properties of the UIElement provided there’s quite easy to extend the functionality a bit for supporting the generics approach.

image

Of course this can also be placed as extension to the Canvas class but my intention was to expose the helper classes that can be implemented at any stage of the project life cycle. Also I think these methods deal with attached properties of UIElement the extension method for Canvas won’t be the right place of storing our generics stuff.

 

2.2. Visual Tree Helper

Standard VisualTreeHelper class contains a lot of important and useful stuff helping developers a lot. Usually I use if for hit testing and it helped me much with rubberband selection tool implementation.

The only thing it lacks very much is the more complicated Parent processing functionality. According to the MSDN forums a lot of people came across one problem related to the control templates and templating stuff.

When dealing with hit testing it’s rather difficult from the first steps provide hit testing features for the elements totally based on Control Templates because hit testing will work for each element within the template separately. Assuming that you might have some sort of shape containing a text box, an image element and something like text block I clearly understand the troubles you might experience when trying to hit-test it or detect clicks.

The only good solution can be found across forums is navigating with the visual tree to get the parent of the Control Template and so find the element required instead of controls within the template. Simple recursive function is quite enough but as I prefer working with generics I’ve implemented another look of the function.

VisualTreeHelperEx.cs

using System.Windows;
using System.Windows.Media;

namespace UsefulExtensions.Helpers
{
  /// <summary>
  /// Provides additional functionality alongside standard VisualTreeHelper.
  /// </summary>
  public static class VisualTreeHelperEx
  {
    /// <summary>
    /// Returns current object or ony parent object that expose the type provided.
    /// Very useful when accessing the main container for the ControlTemplate or for any elements within the ControlTemplate.
    /// </summary>
    /// <typeparam name="T">The type of the object to be searched.</typeparam>
    /// <param name="obj">Starting object to search for parents or itself.</param>
    /// <returns>Returns current object if it exposes the required type or any parent from the upper levels or null.</returns>
    public static DependencyObject GetParent<T>(DependencyObject obj)
    {
      if (obj is T) return obj;

      DependencyObject parent = VisualTreeHelper.GetParent(obj);
      if (parent == null)
        return null;
      else if (!(parent is T))
        return GetParent<T>(parent);

      return parent;
    }
  }
}

As for  hit testing itself you will find a lot of information across the MSDN library so I won’t dwell on it. This method helps getting exactly the element you are looking for when performing the test.

Assume you are implementing the rubberband/multi-selection tool some sort of diagramming application and you definitely know that each of your shape expose something like ISelectable interface. Of course you need to hit-test all the ISelectable based elements on the Canvas. But each you shape also contains a very rich content template making each shape look very fancy. In this case you will simply move to your helper methods defining the shapes regardless their content templates:

 

private List<ISelectable> hits = new List<ISelectable>();
private List<ISelectable> GetSelectablesHit(Geometry region)
{
  hits.Clear();
  GeometryHitTestParameters parameters = new GeometryHitTestParameters(region);
  HitTestResultCallback callback = new HitTestResultCallback(HitTestCallback);
  VisualTreeHelper.HitTest((Visual)DrawingSurface, null, callback, parameters);
  return hits;
}

private HitTestResultBehavior HitTestCallback(HitTestResult result)
{
  GeometryHitTestResult geometryResult = (GeometryHitTestResult)result;

  // Get the object regardless ControlTemplate content
  ISelectable visual = VisualTreeHelperEx.GetParent<ISelectable>(result.VisualHit) as ISelectable;

  if (visual != null &&
    !hits.Contains(visual) &&
    geometryResult.IntersectionDetail == IntersectionDetail.FullyInside)
    hits.Add(visual);
  return HitTestResultBehavior.Continue;
}

You influence the performance a lot because the function doesn’t navigate the element tree each time.

if (obj is T) return obj;

The first line of the function ensures the actual element is what you are querying and stops the recursion. In the rest cases it will go upper level until it founds the required <T> or return null if nothing was found.

 

 

3. Extending interfaces.

As I’ve been using IServiceProvider interface for organizing the basic service bus for my diagramming sample application I again got tired of type casting stuff when querying some service host for the services by their interfaces. So I’ve decided to extend it without any additional inheritance and changes to interface. Extension methods features helped me very much with it. Here’s a quick sample:

IServiceProviderExtension.cs

using System;

namespace UsefulExtensions.Extensions
{
  public static class IServiceProviderExtension
  {
    public static T GetService<T>(this IServiceProvider provider)
    {
      return (T)provider.GetService(typeof(T));
    }

    public static bool Contains<T>(this IServiceProvider provider)
    {
      return (provider.GetService(typeof(T)) != null);
    }
  }
}

What does it give you? In all classes exposing IServiceProvider or interfaces inheriting it you get additional methods GetSetvice and Contains

image

This will help you get rid of common type casting and long strings like

provider.GetService(typeof(ISelectionManager)) as ISelectionManager

by simple

provider.GetService<ISelectionManager>()

Additionally it provides an extension helping you determine whether the service exists within the provider collection. Of course the "Contains" method is just a sample of implementing the extension method.

The best thing as I’ve mentioned above is that you get this extensions to each inheritance case

image

 

The only thing you should remember is adding the namespace of your extension classes to the source files where you deal with IServiceProvider or interfaces exposing it.

Hope this will help anyone to increase the coding performance.

Source code for the article

 
Leave a comment

Posted by on December 15, 2007 in .NET WPF

 

WPF Diagramming. Saving you canvas to image, XPS document or raw Xaml.


Guess saving visuals is one of the most spoken topics today. Main formats I wanted to implement within my application were png, xps and pure xaml so this is what I’ll dwell on below.

Exporting canvas to PNG image

public void ExportToPng(Uri path, Canvas surface)
{
  if (path == null) return;

  // Save current canvas transform
  Transform transform = surface.LayoutTransform;
  // reset current transform (in case it is scaled or rotated)
  surface.LayoutTransform = null;

  // Get the size of canvas
  Size size = new Size(surface.Width, surface.Height);
  // Measure and arrange the surface
  // VERY IMPORTANT
  surface.Measure(size);
  surface.Arrange(new Rect(size));

  // Create a render bitmap and push the surface to it
  RenderTargetBitmap renderBitmap = 
    new RenderTargetBitmap(
      (int)size.Width, 
      (int)size.Height, 
      96d, 
      96d, 
      PixelFormats.Pbgra32);
  renderBitmap.Render(surface);

  // Create a file stream for saving image
  using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
  {
    // Use png encoder for our data
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    // push the rendered bitmap to it
    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
    // save the data to the stream
    encoder.Save(outStream);
  }

  // Restore previously saved layout
  surface.LayoutTransform = transform;
}

I’ve again tried to make the code self-explaining. You can try to use different encoders for saving the data so it’s up to you to look through what ones are available. The main trouble many guys come across is blank images as the canvas output or saving canvas programmatically without visualizing it. The key is measuring and arranging the surface before pushing it to render bitmap. As render bitmap does nothing with measuring and arranging elements in this case, this should be regarded mandatory for you. And of course you should remember the zooming/scaling and rotation matrices ;) the layout transformations will also be saved to the image so you should take care of that manually. In my case I cache the LatoutTransform and reset the original value right before measuring canvas.

Paying more attention you can see that bitmap encoder accepts a Visual so canvas is not the only element that can be passed ;) Going down the inheritance tree it is convenient to use the FrameworkElement or pure Visual. FrameworkElement contains Width and Height properties used by canvas.

Default set references provided by WPF application template is quite enough to implement this method. Of course you’ll have to resolve "using" section ;)

Exporting canvas to XPS document

Actually this was the first I’ve started implementing for my application. I like XPS format very much because it is easy to maintain and integrate. Here’s the quick snippet of exporting your canvas to XPS

public void Export(Uri path, Canvas surface)
{
  if (path == null) return;

  // Save current canvas transorm
  Transform transform = surface.LayoutTransform;
  // Temporarily reset the layout transform before saving
  surface.LayoutTransform = null;

  // Get the size of the canvas
  Size size = new Size(surface.Width, surface.Height);
  // Measure and arrange elements
  surface.Measure(size);
  surface.Arrange(new Rect(size));

  // Open new package
  Package package = Package.Open(path.LocalPath, FileMode.Create);
  // Create new xps document based on the package opened
  XpsDocument doc = new XpsDocument(package);
  // Create an instance of XpsDocumentWriter for the document
  XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
  // Write the canvas (as Visual) to the document
  writer.Write(surface);
  // Close document
  doc.Close();
  // Close package
  package.Close();

  // Restore previously saved layout
  surface.LayoutTransform = transform;
}

You will need two additional assemblies to be referenced from the GAC: "ReachFramework.dll" and "System.Printing.dll". Again I’d advice you to backup the original layout transformation regardless it’s state before processing canvas. You should definitely read more details towards System.IO.Packaging and XPS documents. For those who doesn’t know yet the XPS document is presented by zip container for some xml, fonts and binary data like images etc. You can freely rename XPS to ZIP, unpack it and look inside for better understanding when you’ll be looking though MSDN articles towards it.

I was really pleased to find out that 10 or 20 of my duplicated elements having the same image with content template loaded from the separate assembly wasn’t cloned. I had only one image in the XPS for each distinct type of element so the archive size was extremely small for my diagram.

Exporting canvas to the XAML

I’ll give you the most stupid sample that can be found everywhere

public void Export(Uri path, Canvas surface)
    {
      if (path == null) return;
      if (surface == null) return;

      string xaml = XamlWriter.Save(surface);
      File.WriteAllText(path.LocalPath, xaml);
    }

You get the xaml presentation of your canvas that can be later loaded with XamlReader. Be prepared to cuss MS guys a lot because it is rather difficult to adopt any application load anything except simple xamls into your canvas :) The worst thing is that it doesn’t support bindings/multibindings so you’ll have to resolve them somehow on document loading. The same is for events and there’s a list of things not supported that can be easily found at MSDN shipped with Visual Studio. I’ve looked through the Internet to find any good solution but there’s nothing I liked. Guess if it becomes a hot topic (and I’m sure it will become soon) a lot of good overrides will appear. I’m doing my own implementation but it’s in the early stage and cannot be brought to public.

Anyway there’s a lot of cases when the pure xaml will be quite enough for you.

Have a nice coding and investigations.

 
6 Comments

Posted by on December 3, 2007 in .NET WPF

 

WPF Diagramming. Undo/Redo service and simple commands.


Undo/Redo functionality can be regarded as one of the most important parts of application and not because of it’s complexity. This feature can influence the architecture of your application very much (of course if you didn’t implement the commands pattern from the beginning) and can make you spend a lot of time for refactoring.

Each action in the application can be regarded as some single command. The command knows how to execute an action and so it should know how to undo or redo it easily. In order to provide the list of user-friendly names of commands to be undone the it can also contain some title to be distinguished in the UI. So the basic interface for it can be as following

public interface IDiagramCommand
  {
    /// <summary>
    /// Executes the actual action
    /// </summary>
    void Execute();

    /// <summary>
    /// Executes an action corresponding to an undo
    /// </summary>
    void Undo();

    /// <summary>
    /// Executes an action corresponding to redo in case it has been undone.
    /// </summary>    
    void Redo();

    /// <summary>
    /// Title of the command.
    /// </summary>
    /// <remarks>Typically to be used in undo list or undo stack description.</remarks>
    string Title { get; set; }
  }

Assume you are adding a shape to the canvas and this action should be undone on demand. The action command should be common for all your elements based on UIElement and know the surface it is operating. In my case extended canvas will be the command surface. This is the most common information needed the first simple command.

I’ve implemented some additional helper methods for the canvas and pass my common interface over the commands.

public interface IDrawingSurface: IInputElement
  {
    /// <summary>
    /// Get/Set the value indicating whether elements dragging is allowed for the canvas.
    /// </summary>
    bool IsDragEnabled { get; set; }

    /// <summary>
    /// Add generic element to the surface
    /// </summary>
    /// <typeparam name="T">UIElement type</typeparam>
    /// <param name="element">Element to be added to the surface</param>
    void AddElement<T>(T element);

    /// <summary>
    /// Insert generic element to the surface at a specified index position.
    /// </summary>
    /// <typeparam name="T">UIElement type</typeparam>
    /// <param name="index">The position of element to be placed</param>
    /// <param name="element">Element to be inserted to the surface</param>
    void InsertElement<T>(int index, T element);

    /// <summary>
    /// Remove generic element from the surface
    /// </summary>
    /// <typeparam name="T">UIElement type</typeparam>
    /// <param name="element">Element to be removed from the surface</param>
    void RemoveElement<T>(T element);
  }

 

Using generics in this case help me very much eliminating the type casting and the stuff like that. As canvas deals with UIElement based elements it becomes rather difficult maintaining the collection because I definitely sure you won’t deal with UIElement objects all over you application. It becomes more convenient to wrap the basic child processing logic into some sort of generic helpers.

The simple pieces of code for the canvas exposing such an interface can be as following

/// <summary>
/// Add generic element to the surface
/// </summary>
/// <typeparam name="T">UIElement type</typeparam>
/// <param name="element">Element to be added to the surface</param>
public void AddElement<T>(T element)
{
  UIElement uiElement = element as UIElement;
  if (uiElement != null && !Children.Contains(uiElement))
    Children.Add(uiElement);
}

 

The remove or insert methods are too obvious to be mentioned here. You can implement you own subset of functionality extending the canvas using your own demands.

As I’ve mentioned earlier the simple add element command that can satisfy the undo/redo service should have the possibility of adding some kind element to the drawing surface (command execution), remove the element from the surface (undo operation) and rollback the undo operation so add the element again to the surface (redo operation).

public class AddElementCommand : IDiagramCommand
  {
    public const string DefaultCommandTitle = "Add Element";

    #region Properties
    /// <summary>
    /// Gets or sets the surface.
    /// </summary>
    /// <value>The surface.</value>
    public IDrawingSurface Surface { get; set; }

    /// <summary>
    /// Gets or sets the element.
    /// </summary>
    /// <value>The element.</value>
    public UIElement Element { get; set; }

    /// <summary>
    /// Title of the command.
    /// </summary>
    /// <value></value>
    /// <remarks>Typically to be used in undo list or undo stack description.</remarks>
    public string Title { get; set; }
    #endregion

    #region ctor
    /// <summary>
    /// Initializes a new instance of the <see cref="AddElementCommand"/> class.
    /// </summary>
    /// <param name="surface">The surface.</param>
    /// <param name="element">The element.</param>
    public AddElementCommand(IDrawingSurface surface, UIElement element) : this(surface, element, null) { }

    /// <summary>
    /// Initializes a new instance of the <see cref="AddElementCommand"/> class.
    /// </summary>
    /// <param name="surface">The surface.</param>
    /// <param name="element">The element.</param>
    /// <param name="title">The title.</param>
    public AddElementCommand(IDrawingSurface surface, UIElement element, string title)
    {
      if (surface == null) throw new ArgumentNullException("surface");
      if (element == null) throw new ArgumentNullException("element");
      
      Surface = surface;
      Element = element;
      Title = (!string.IsNullOrEmpty(title)) ? title : DefaultCommandTitle;
    }
    #endregion

    #region IDiagramCommand Members
    /// <summary>
    /// Executes the actual action
    /// </summary>
    public void Execute()
    {
      Surface.AddElement(Element);
    }

    /// <summary>
    /// Executes an action corresponding to an undo
    /// </summary>
    public void Undo()
    {
      Surface.RemoveElement(Element);
    }

    /// <summary>
    /// Executes an action corresponding to redo in case it has been undone.
    /// </summary>
    public void Redo()
    {
      Surface.AddElement(Element);
    }
    #endregion
  }

The command itself doesn’t create the UI element because it is not responsible for that. It even doesn’t distinguish your objects being passed. It only assumes the objects belong to UIElement type and that’s all. As far as you can understand the undo/redo service is also blind to the content of the commands it deals with. It will process the IDiagramCommand objects and will attach it’s undo/redo functionality to each command.

Here’s the what could be the simple interface for basic undo/redo service

public interface IUndoService
  {
    /// <summary>
    /// Get the undo commands history.
    /// </summary>
    Stack<IDiagramCommand> UndoCommands { get; }

    /// <summary>
    /// Get the redo commands history.
    /// </summary>
    Stack<IDiagramCommand> RedoCommands { get; }

    /// <summary>
    /// Get the undo commands titles.
    /// </summary>
    ObservableCollection<string> UndoTitles { get; }

    /// <summary>
    /// Get the redo commands titles.
    /// </summary>
    ObservableCollection<string> RedoTitles { get; }

    /// <summary>
    ///  Gets a value indicating whether there is anything that can be undone.
    /// </summary>
    bool CanUndo { get; }

    /// <summary>
    /// Gets a value indicating whether there is anything that can be rolled forward.
    /// </summary>
    bool CanRedo { get; }

    /// <summary>
    /// This method puts the command to the Undo stack and then executes it.
    /// </summary>
    /// <param name="command">The command to be executed.</param>
    void Execute(IDiagramCommand command);

    /// <summary>
    /// Rollback the last command.
    /// </summary>
    void Undo();

    /// <summary>
    /// Rollback the last undone command.
    /// </summary>
    void Redo();

    /// <summary>
    /// Clear the undo history.
    /// </summary>
    void ClearUndoHistory();

    /// <summary>
    /// Clear the redo history.
    /// </summary>
    void ClearRedoHistory();

    /// <summary>
    /// Clear all the undo and redo history.
    /// </summary>
    void ClearHistory();
  }

Hope the code is self explaining. We introduce two stacks for commands according to undo and redo implementation. Also we have two observable collections giving the titles. Also we provide the obvious Execute/Undo/Redo methods alongside with a set of helper methods and properties as clearing the history or returning a boolean value determining whether this or that functionality as possible at execution time.

Here’s the Undo/Redo service that expose the interface mentioned above

public class UndoService : IUndoService
  {
    #region ctor
    public UndoService()
    {
      UndoCommands = new Stack<IDiagramCommand>();
      UndoTitles = new ObservableCollection<string>();
      RedoCommands = new Stack<IDiagramCommand>();
      RedoTitles = new ObservableCollection<string>();
    } 
    #endregion

    #region Routed events bindng support
    public void OnExecuteUndo(object sender, ExecutedRoutedEventArgs e)
    {
      Undo();
    }

    public void OnCanExecuteUndo(object sender, CanExecuteRoutedEventArgs e)
    {
      e.CanExecute = CanUndo;
    }

    public void OnExecuteRedo(object sender, ExecutedRoutedEventArgs e)
    {
      Redo();
    }

    public void OnCanExecuteRedo(object sender, CanExecuteRoutedEventArgs e)
    {
      e.CanExecute = CanRedo;
    }
    #endregion

    #region IUndoService Members
    /// <summary>
    /// Get the undo commands history.
    /// </summary>
    public Stack<IDiagramCommand> UndoCommands { get; protected set; }

    /// <summary>
    /// Get the redo commands history.
    /// </summary>
    public Stack<IDiagramCommand> RedoCommands { get; protected set; }
    
    /// <summary>
    /// Get the undo commands titles.
    /// </summary>
    public ObservableCollection<string> UndoTitles { get; protected set; }

    /// <summary>
    /// Get the redo commands titles.
    /// </summary>
    public ObservableCollection<string> RedoTitles { get; protected set; }

    /// <summary>
    ///  Gets a value indicating whether there is anything that can be undone.
    /// </summary>
    public bool CanUndo { get { return UndoCommands.Count > 0; } }

    /// <summary>
    /// Gets a value indicating whether there is anything that can be rolled forward.
    /// </summary>
    public bool CanRedo { get { return RedoCommands.Count > 0; } }

    /// <summary>
    /// This method puts the command to the Undo stack and then executes it.
    /// </summary>
    /// <param name="command">The command to be executed.</param>
    public void Execute(IDiagramCommand command)
    {
      if (command == null) return;
      // Execute command
      command.Execute();
      // Push command to undo history
      if (command is IDiagramCommand)
      {
        UndoCommands.Push(command);
        UndoTitles.Insert(0, command.Title);
        // Clear the redo history upon adding new undo entry. This is a typical logic for most applications
        RedoCommands.Clear();
        RedoTitles.Clear();
      }
    }

    /// <summary>
    /// Rollback the last command.
    /// </summary>
    public void Undo()
    {
      if (CanUndo)
      {
        IDiagramCommand command = UndoCommands.Pop();
        command.Undo();
        UndoTitles.RemoveAt(0);
        RedoCommands.Push(command);
        RedoTitles.Insert(0, command.Title);
      }
    }

    /// <summary>
    /// Rollback the last undone command.
    /// </summary>
    public void Redo()
    {
      if (CanRedo)
      {
        IDiagramCommand command = RedoCommands.Pop();
        RedoTitles.RemoveAt(0);
        //Execute(command);
        if (command != null)
        {
          command.Execute();

          if (command is IDiagramCommand)
          {
            UndoCommands.Push(command);
            UndoTitles.Insert(0, command.Title);
          }
        }        
      }
    }

    /// <summary>
    /// Clear the undo history.
    /// </summary>
    public void ClearUndoHistory()
    {
      UndoCommands.Clear();
      UndoTitles.Clear();
    }

    /// <summary>
    /// Clear the redo history.
    /// </summary>
    public void ClearRedoHistory()
    {
      RedoCommands.Clear();
      RedoTitles.Clear();
    }

    /// <summary>
    /// Clear all the undo and redo history.
    /// </summary>
    public void ClearHistory()
    {
      ClearRedoHistory();
      ClearUndoHistory();
    }
    #endregion
  }

The code above mostly doesn’t require long supplementary information. On each command execution the redo stack is cleared to reflect the most common behavior in all applications. The undo and redo methods mainly do the manipulations with theirs stacks and corresponding title collections. The main entry point for the undo service is Execute method. It executes the command and adds it to the undo stack (great thanks to François for that idea)

The only part that can be a point of detailed interest is the region "Routed events binding support". These four methods provide an easy and convenient possibility of binding the undo/redo commands to the UI. Usually you’ll have two buttons and maybe each button will contain the list of operation titles for undoing of redoing.

In my sample projects I usually implement two buttons bound to the standard application commands.

<Button Margin="0,3" Name="cmdUndo" Command="ApplicationCommands.Undo">
    <StackPanel>
        <Image Source="Images/undo.png" Width="32" Height="32"/>
        <TextBlock>Undo</TextBlock>
    </StackPanel>
</Button>
<Button Margin="0,3" Name="cmdRedo" Command="ApplicationCommands.Redo">
    <StackPanel>
        <Image Source="Images/redo.png" Width="32" Height="32"/>
        <TextBlock>Redo</TextBlock>
    </StackPanel>
</Button>

Take a look at the "Command" property of each button. "ApplicationCommands" is a standard class so if interested you look through MSDN to get more information and use cases.

Upon the window loading I attach my undo/redo logic to the list of command bindings for the window so that buttons accessing "ApplicationCommands.Undo" and "ApplicationCommands.Redo" automatically go to my UndoService.

Something like the following

#region Configure command bindings
UndoService undoService = designer.GetService<IUndoService>() as UndoService;
if (undoService != null)
{
  this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, undoService.OnExecuteUndo, undoService.OnCanExecuteUndo));
  this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, undoService.OnExecuteRedo, undoService.OnCanExecuteRedo));
}
#endregion

OnCanExecuteUndo and OnCanExecuteRedo methods are returning the CanUndo and CanRedo properties of the underlying Undo/Redo service. The last two mentioned are bound to the corresponding stacks and return true if the stack contains any command.

This gives you a very interesting feature. Your buttons will themselves control their state and will become enabled/disabled according to the contents of undo/redo stacks.

This is a very basic pattern to get the idea of implementing undo/redo functionality and commands. It’s up to you what commands will be executed and what will they do. The undo/redo service is usually implemented in the way it doesn’t take care of that. It deals with interface part of commands and that’s all.

Thanks for your attention. The sources can be found at my skydrive under "Diagramming" folder or in the previous article.

 
2 Comments

Posted by on November 24, 2007 in .NET WPF

 
 
Follow

Get every new post delivered to your Inbox.

Join 71 other followers

%d bloggers like this: