Silverlight 3 PropertyGrid Development Progress

October 31, 2009 Denis Vuyka Leave a comment

There was no information about Silverlight version of the PropertyGrid control for some period. I would like to leak some information towards the current development progress as well as highlight some of the most remarkable features.

Multiple layouts support

Silverlight PropertyGrid will support at least Alphabetical and Categorized layouts out-of-box. There will be a possibility to write your own layouts with least amount of efforts possible.

Here’s how the the “Categorized” one looks like and defined in XAML:

SPG01

SPG02

“Categorized” layout will be the default one. This means that you won’t need defining anything if “Categorized” behavior is those you expect to have by default.

Note that control will support “Description Box” similar to native Windows Forms PropertyGrid control.

Here’s how the “Alphabetical” layout looks like and defined in XAML:

SPG03

SPG04

Both POCO (Plain Old CLR Objects) and Dependency objects are to be supported. Here’s the Button control bound to PropertyGrid:

SPG05

Property Filtering feature will provide exactly the same functionality Microsoft Expression Blend’s PropertyGrid control gives. It will be possible to filter out properties according to their names and types:

SPG06

SPG07

After Silverlight 3 went RTM the Silverlight PropertyGrid development progress went rapid and smooth and hopefully the control will be available very soon.

More news are coming soon…

Categories: .NET, Silverlight

Reflection Limitation in .NET 3.5/4.0

October 26, 2009 Denis Vuyka Leave a comment

Recently a colleague of mine pointed to a strange behavior in .NET Reflection  that pushed me doing a lot of additional investigations and finding out a very serious limitation that might raise a lot of issues if not being taken into account.

When you declare property as “virtual” beware that custom attributes won’t be fetched for the derived one if the property is being overrided.

This can be easily tested. First you need creating two custom attributes that will target two cases: virtual property and virtual method.

  [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  public class MyPropertyAttribute : Attribute
  {
  }

  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public class MyMethodAttribute : Attribute
  {
  }

Now you can create two classes: “BaseClass” that will contain a single virtual property and single virtual method and “DerivedClass” that will override both members.

 public class BaseClass
  {
    private string _PropertyVirtual;

    [MyProperty]
    public virtual string PropertyVirtual
    {
      get { return _PropertyVirtual; }
      set { _PropertyVirtual = value; }
    }

    [MyMethod]
    public virtual void MethodVirtual()
    {
    }
  }

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      base.MethodVirtual();
    }
  }

The problem starts when you try fetching custom attributes for “PropertyVirtual” from within a DerivedClass because you will never get them using PropertyInfo.GetCustomAttributes method call. Here’s a sample Console Application to ensure the limitation is alive:

  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Checking virtual property attributes:\r\n");

      Console.WriteLine(
        "BaseClass.PropertyVirtual attributes count: {0}",
        typeof(BaseClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        typeof(DerivedClass).GetProperty("PropertyVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine("\r\nChecking virtual method attributes:\r\n");

      Console.WriteLine(
        "BaseClass.MethodVirtual attributes count: {0}",
        typeof(BaseClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.WriteLine(
        "DerivedClass.MethodVirtual attributes count: {0}",
        typeof(DerivedClass).GetMethod("MethodVirtual").GetCustomAttributes(true).Length);

      Console.ReadLine();
    }

Upon running this sample you should see the following results:


Checking virtual property attributes:

BaseClass.PropertyVirtual attributes count: 1
DerivedClass.PropertyVirtual attributes count: 0

Checking virtual method attributes:

BaseClass.MethodVirtual attributes count: 1
DerivedClass.MethodVirtual attributes cound: 1

As you can ensure there are no custom attributes returned for overrided virtual property while the expected result is fetched for overrided virtual method.

You can easily find what is happening under the hood if switching to MSIL representation of the classes coded above. Here’s how the “BaseClass” attribute usage looks like:

Reflection Issue 1

As you can see on the IL level “MethodVirtual” declares “MyMethodAttribute” instance right within its own body. The same goes for “PropertyVirtual” – a getter, a setter and attribute declaration.

However both members look like the following when derived:

Reflection Issue 2

While “MethodVirtual” still refers to “base.MethodVirtual” and theoretically can invoke attribute declaration,

note that the following overriding will still work for methods:

  public class DerivedClass : BaseClass
  {
    public override string PropertyVirtual
    {
      get { return base.PropertyVirtual; }
      set { base.PropertyVirtual = value; }
    }

    public override void MethodVirtual()
    {
      //base.MethodVirtual();
    }
  }

“PropertyVirtual” is no longer related to a base implementation. We have a completely new property definition that is wired with base getter and setter. But no custom attribute declaration!

This means that the default code written for MemberInfo class won’t be able fetching anything except empty object array.

There are two workarounds I found that help switching to another MS developer(s) work, custom attribute fetching seems to be completely different in the following approaches: TypeDescriptor and old-fashioned Attribute class.

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        Attribute.GetCustomAttributes(typeof(DerivedClass).GetProperty("PropertyVirtual"), typeof(MyPropertyAttribute)).Length);

The code above will be able to fetch and display custom attributes for a virtual property. Same can be achieved by means of property descriptors:

      Console.WriteLine(
        "DerivedClass.PropertyVirtual attributes count: {0}",
        TypeDescriptor.GetProperties(typeof(DerivedClass))["PropertyVirtual"].Attributes[typeof(MyPropertyAttribute)] != null);

However the last one will have a great performance overhead in comparison with the “Attribute.GetCustomAttributes” usage.

I’ve tested the same issue with .NET 4.0 (beta 2) and it is still there. I really hope this article will help you detecting problems with your software and eliminating issues related to this very case.

You can find the source code for this article here: MetadataIssue

Categories: .NET

WPF PropertyGrid 2.0. Fully functional demo.

May 29, 2009 Denis Vuyka 4 comments

Today the WPG product page became available for public access at Orbifold!

Feel free download the fully functional (but slighly nagged) demo that includes some of the samples, API documentation and getting started guide.

WPG 2.0 Fully Functional Demo

Categories: WPF

WPF PropertyGrid: Telerik WPF Controls 2009 Integration Kit

May 21, 2009 Denis Vuyka 2 comments

I’m glad to announce that we are going to include a “Telerik WPF Controls 2009” Integration Kit into every “Orbifold WPF PropertyGrid 2.0″ package. This is a quick start WPF project demonstrating how easily Telerik Controls 2009 can be used for property editing within the Orbifold PropertyGrid control. Getting started guide will also be upgraded to cover Telerik integration steps.

WPG 2.0 Fully Functional Demo

It should take less than an hour to reproduce the given project. The screenshots are given below.

Color Picker

WPG_Color_01

WPG_Color_02

Date and Time Pickers

WPG_DateTime_01

WPG_DateTime_02

WPG_DateTIme_03

Masked Editors (Date and Time)

WPG_Masked_01

Masked Editors (General)

WPG_Masked_02

Numeric Editors

WPG_Numeric_01

Hope you will enjoy this kit.

Orbifold WPF PropertyGrid 2.0 is out

May 15, 2009 Denis Vuyka 2 comments

Today I’m glad to announce that Orbifold WPF PropertyGrid version 2.0 is finally out. I want to thank all the companies that took part in the beta experience program during last two months and gave me valuable feedback.

Starting from Monday (May 17, 2009) PropertyGrid control will be available for purchase. Pricing will be as folows:

200$ for single developer license (binaries, getting started guide)

500$ for site license (binaries, sources + unit tests, getting started guide)

Both packages will include 1 year of free updates and email support.

Please send an Email to sales[@]orbifold.net if you are interested in purchasing PropertyGrid control.

WPG 2.0 Fully Functional Demo

Details on the release version:

PropertyGrid is still following .Net Windows Forms PropertyGrid and Expression Blend PropertyGrid paradigm. About 70% of old codebase was rewritten or refactored in order to minimize developers efforts and make enty barrier as low as possible.

The most remarkable features are the following:

Multiple Objects Selection

Both single and multiple objects selection is fully supported. Categories (if property grid is set to Categorized mode) preserve their viewstates when changing amount of objects selected or switching between different objects. MergablePropertyAttribute is supported for scenarios when there’s a need to exclude some of the properties from multi-selection editing.

Separate Themes

No theme is applied by default so it is easy to apply internal corporate or custom themes. Extenal themes were moved to a separate “Themes” assembly (by default version 2.0 supports original black also known as “Kaxaml” theme). Each theme can be applied either to PropertyGrid or overall Window/Application.

WPG 2.0 Default View

WPG 2.0 Default Kaxaml Theme

Vista Explorer-like Property Filter Box

As it can be seen from the screenshots above a brand new property filter box was introduced in this version. It occupies less space and can be switched of/on by means of appropriate properties from either XAML or code. Like Expression Blend, property filtering supports filtering both by property display names and property types.

Custom Categories

Full support for custom categories. It is now possible providing any layout for the whole category. Layoutting procedure is as close as possible to Microsoft custom categories guides. The screenshot below demonstrates custom category layout copy-pasted from MSDN site: “Walkthrough: Creating a Category Editor”.

WPG 2.0 Custom Category

Rich Insfrastructure For Property and Category Editors

There are several ways declaring editors for your business objects or view models. You can declare an editor for a Type, for single property of the Type or an editor for the whole category. Editors can be declared via XAML, code behind or custom attributes. Besides edited value each editor has access to owning property grid control and all the metadata (custom attributes the edited property is marked with). It is easy binding controls in editor template directly to metadata values (like marking property with some Range attribute and binding Slider editor values to Range.Minimum and Range.Maximum). Category Editor control parts can be easily bound to different properties directly from XAML.

There is a set of default common types editors. The ways introducing custom editors for properties and categories as long as organizing editor control templates are extremely easy and vary.

More Access Over Property Items and Categories

It is possible gaining explicit control over properties regardless initial property state. You can control whether and when to show or hide any property (especially usefull when introducing conditionally visible properties or complex editors). The same goes for Categories. PropertyGrid provides effient infrastucture accessing properties and items by names either from code behind or XAML. Object model allows you configuring properties and categories easily. There is a set of attributes that allow defining property orders, controlling visibility of properties/categories without having access to them and without the need to override/replace properties of parent Type just in order to mark them with some attribute.

Custom Layout

PropertyGrid allows you configuring different Views for your business objects. You can choose whether to use a single or multiple views (Property Tabs) within your application. By default there are three modes supported: Categorized, Alphabetical and Tabbed layouts. Tabbed Layout allows you combining Views on several pages. You can totally replace PropertyGrid presentation with a custom View based on existing infrastructure. Developer guide will give you a sample on how to display each Category of the the edited object in a separate property tab easily just by modifying XAML markup in your application.

Extended Editors

This is a unique feature allowing you opening property editors within separate property tabs. You can have a “Basic” or inline editor covering most common scenarios and “Extended” editor providing more complex UI. Each extened editor occupies full separate Tab and can be closed by user (there’s a way restricting tabs to be closed if required). It is supported natively by default Tabbed Layout however PropertyGrid model allows you implementing your own Views that suport this very feature.

Dialog Editors

Dialog editors are also supported. You can embed dialog logic into your custom editors or intercept dialog calls in order to provide external editing support within your application.

There are a lot more usefull features supported for the moment. More details will be covered within “getting started guide” and blog posts soon.

WPF PropertyGrid 2.0

March 25, 2009 Denis Vuyka Leave a comment

I’ve received a lot of questions regarding WPF PropertyGrid control at Codeplex (codeplex.com/wpfpropertygrid) and why the link is no longer available. Everybody wanted to know whether the project support was discontinued at all or it was related to technical problems. Here’s a short disclaimer towards the changes happened to the project.

Starting from Monday (March 23, 2009) the support for Community (or Open Source) version 1.x of the control was indeed discontinued in favor of Professional (or Commerical) Version 2.x that has been developed in parallel…

Why?

Community version (1.x)

Pros.

  • Provides developer experience towards how the things are working in the world of property editing
  • Provides source code that can be extended, bug-fixed or adopted to specific scenarios
  • Competes with Close Source controls :)
  • Good to use in home projects

Cons.

  • Feature development as well as bug fixing is infrequent
  • Development team decides which feature to include first sometimes regardless what is really required
  • Email support is optional
  • Cannot be used in commercial applications simply because companies cannot be sure regarding the future of the control they choose
  • Misses various features required for business applications
  • No product support in its common sense
  • Project often don’t have sponsorship, donations or commerical license requiests so the developers invest their own time and money that in most cases leads to product degradation :(

Professional version (2.x)

It has been developed in parallel with Community version thus having slighly different codebase and more efficient feature set.

Pros.

  • Frequent updates and bug fixes
  • Rapidly evolving feature set
  • Maximum API parity with Windows Forms .Net PropertyGrid (including nested types and multiple objects selected), all the features required by a common business application
  • Email support
  • Free maintenance updates
  • Specific features requests either separatelly or per support basis.

Cons.

  • No Open Source support.
  • Needs to be purchased :)

So in order the project to survive and evolve even more rapidly the second way was chosen.

WPF PropertyGrid 2.x will be available at least in two editions “Single Developer” and “Site (+sources)”. Both of them will contain the standard set of support features like:

  • Free product updates to a new version for a year
  • Maintenance updates for a purchased version
  • Email support for a purchased version and updated versions
  • Royalty-free distribution rights

Version 2.x contains slighly different codebase based on various enhancements and improvements from both funtional and performance views comparing to Community version of the control. Less steps are required to perform most of the configuration and customization actions, more ComponentModel members are supported, greatly improved API and stabilized code. 

More detailed information towards the new features and benefits as well as release date and prices is coming soon… 

P.S. If you need a license as well as support and product updates before the product is officially released feel free to contact me directly at “denisvuyka[at]live[dot]com”

Categories: Info Tags: ,

First WPF Parallel Coordinates Control

March 20, 2009 Denis Vuyka 2 comments

I’m glad to announce that together with Francois Vanderseypen we’ve successfully introduced the first WPF Parallel Coordinates Control for a customer of ours! At least I could not find any one in the Google for the moment of writing this article ;)

“ParaGraph” is capable of displaying any types of data like strings, doubles, datetimes, etc. and can be easily bound to a DataTable instance. It has no problems visualizing CSV/Spreadsheet data bound to it. The control it is highly customizable and nearly every visual feature can be switched off/on as well as configured either via xaml and control templates or code behind settings.

The Demo Application demonstrating basic functionality can be found here

1. Overall look of the demo application:

 

image1-overall-look1

2. Support for Background Grid and Range labels:

image2-background-grid-and-range-labels3

3. Lines Highlighting and Tooltips

image3-line-highlighting-and-tooltips1

4. Histogram (Emphasizing the Accumulation Points)

image4-histogram1

5. Axes scaling (zooming in and out)

image5-axes-scaling1

By default control resides in “Swap” mode. You can drag each single Axis to a different location in order to change (swap) them immediately with redrawing of all corresponding data values. 

6. Line Thickness/Hover Thickness

image6-line-and-hover-thickness1

These are the key features I wanted to highlight but not the all amount ;)

For more details please refer also to the initial announcement here.

Bringing MEF to Xaml via MarkupExtension

February 23, 2009 Denis Vuyka Leave a comment

Nearly a year ago I was playing with Unity container in the scope of pure Xaml and Markup extensions. There was a 4-part series of articles on my old blog: 

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

This time I’ve decided to continue my extreme development and to try injecting UI controls into WPF layout directly from MEF :)

Note that this is an experimental stuff, I know about Prism/CompositeWPF and many other things. I was just intrested whether it is possible do it the way I did  ;)

1. Preparing Layout

I wanted to have something like the following:

<Window
  x:Class="XamlifiedMEF.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:XamlifiedMEF"
  Title="Xamlified MEF" Height="600" Width="800">

  <StackPanel>
    <local:MefPart Contract="TextBoxPart"/>
    <ItemsControl ItemsSource="{local:MefPart Contract=ButtonPart}"/>
  </StackPanel>

</Window>

where the StackPanel element imports one TextBox (via the “TextBoxPart” contract) and additionally nests a single ItemsControl having an ItemsSource as a collection of exported Button elements (via the “ButtonPart” contract).

2. MEF Locator

As a common Xaml MarkupExtension cannot be imported or built up via some sort of ObjectBuilder (in order to get dependencies injected) you might need some static entry point (Service Locator). I recommend reading the article “CommonServiceLocator for MEF, a service is a service”  by Glenn Block or referring to codeplex version of CommonServiceLocator

In my case I simply decided to use the static class in order to get access to CompositionContainer:

namespace XamlifiedMEF
{
  internal static class Mef
  {
    private static readonly CompositionContainer _container;
    public static CompositionContainer Container
    {
      get { return _container; }
    }

    static Mef()
    {
      _container = new CompositionContainer(
        new AssemblyCatalog(
          Assembly.GetExecutingAssembly()));
    }
  }
}

 Of course in “real” implementations this service might require proper implementaiton and configuration but I left it simple for clarification purposes.

3. Parts

Next thing you will need is defining a couple of parts to be injected/imported into the layout. I’ve created a dummy textbox and three buttons:

namespace XamlifiedMEF
{
  [Export("TextBoxPart")]
  public class TextBoxPart : TextBox
  {
    public TextBoxPart()
    {
      this.Text = "Hi, I'm imported text part";
    }
  }

  [Export("ButtonPart")]
  public class Button1 : Button
  {
    public Button1()
    {
      this.Content = "I'm a button part 1";
    }
  }

  [Export("ButtonPart")]
  public class Button2 : Button
  {
    public Button2()
    {
      this.Content = "I'm a button part 2";
    }
  }

  [Export("ButtonPart")]
  public class Button3 : Button
  {
    public Button3()
    {
      this.Content = "I'm a button part 3";
    }
  }
}

The samples above are fairly simple and guess need no comments ;)

4. Markup Extension

And finally you will need a simple markup extension that will get one or several parts from the MEF container. Here’s the smallest extension that could be implemented in this case:

namespace XamlifiedMEF
{
  [MarkupExtensionReturnType(typeof(FrameworkElement))]
  public class MefPartExtension : MarkupExtension
  {
    [ConstructorArgument("Contract")]
    public string Contract { get; set; }

    public MefPartExtension()
    {
    }

    public MefPartExtension(string contract)
    {
      this.Contract = contract;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
      ExportCollection<FrameworkElement> exports =
        Mef.Container.GetExports<FrameworkElement>(Contract);

      if (exports.Count == 0) return null;
      if (exports.Count == 1) return exports[0].GetExportedObject();

      var items = from Export<FrameworkElement> item
                    in exports
                  select item.GetExportedObject();

      return items;
    }
  }
}

Note:  The extension is marked with FrameworkElement return type in case a single UI part is imported.

The core of the extension is “ProvideValue” method that should be always implemented. You will need to get the collection of exports by provided contract name. Next I determine whether ther resulting collection contains one element or several and return the values according to the result.

When you will launch the application you will see that all the declared elements were successfully imported into the layout. 

Demo project can be downloaded here…

Categories: WPF Tags: , , ,

Using EventAggregator with MEF

February 21, 2009 Denis Vuyka 3 comments

Recently I was seeking for a possibility making MEF parts to respond host application as well as neighbouring parts events in a weak way. Actually I was looking for some sort of Event Broker similar to that coming as a Unity Sample (Enterprise Library 4.x). For the moment MEF (MEF 4 preview) does not support importing and exporting events or multicast delegates so custom solutions are required in order to accomplish such task. From one side I didn’t want mixing MEF with Unity/ObjectBuilder in order to inject event publications/subscriptions. From the other side I didn’t want mixing MEF with Composite WPF (former Prism) though I like their awesome EventAggregator very much. 

After analysing CompositeWPF sources I found out that EventAggregator is presented by a completely isolated part having no dependencies on the rest of the library. So it means that it can be easily used outside the assembly without any implications. This was something I needed very much.

Extracting EventAggregator into a separate assembly takes a couple of minutes assuming that you have downloaded the sources. Implementing a simple MEF-powered application also takes a couple of minutes. MEF project got a useful set of samples within their wiki. Sample application demonstrating the use of EventAggregator with MEF as long as the extracted EventAggregator code can be found at the end of this article…

Small walkthrough

I will show how a simple user message can be broadcasted by an application and processed by a control that was imported from a MEF Catalog and injected into the main application layout

1. Preparing a simple message event

First of all you need to define a message format that will be sent to external components. It can be defined by the following class:

  public class UserMessage
  {
    public string Text { get; set; }

    public UserMessage(string text)
    {
      this.Text = text;
    }
  }

Next you have to define an event body that external components will be subsribing to. Hosting application will also use it for raising a message event:

   public sealed class UserMessagePostedEvent
    : CompositePresentationEvent<UserMessage>
  {
  }

You don’t need providing additional memebers to this class as CompositePresentaionEvent<T> already contains everything needed.

2. Preparing a simple event consumer

Now you need to define a MEF part that will be consuming user message events raised by hosting application or neighbours. Let’s turn a standard WPF TextBox into a MEF part:

  [Export("EventViewer")]
  public class EventViewer : TextBox, INotifyImportSatisfaction
  {
    [Import]
    private IEventAggregator eventAggregator;

    private SubscriptionToken subscriptionToken;

    #region INotifyImportSatisfaction Members

    public void ImportCompleted()
    {
      if (eventAggregator != null)
      {
        UserMessagePostedEvent messagePostedEvent =
          eventAggregator.GetEvent<UserMessagePostedEvent>();

        if (subscriptionToken != null)
          messagePostedEvent.Unsubscribe(subscriptionToken);

        subscriptionToken = messagePostedEvent.Subscribe(
          OnUserMessagePosted,
          ThreadOption.UIThread,
          false);
      }
    }

    private void OnUserMessagePosted(UserMessage message)
    {
      this.Text += Environment.NewLine + message.Text;
    }

    #endregion
  }

Note that Textbox called EventViewer imports EventAggregator via its IEventAggregator interface. Next on ImportCompleted event it creates a subscription token for UserMessagePostedEvent you’ve created earlier. After that subcription is wired with OnUserMessagePosted handler that will add received message text to a TextBox text.

3. Preparing a Window layout

Now you need creating some debugging layout to ensure application can raise events and imported parts can handle and react on messages. Here’s the simple xaml for the testing window:


<Window
  x:Class="EventAggregatorForMEF.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="EventAggregator for MEF" Height="600" Width="800">

  <Grid Name="LayoutRoot">
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Button Name="SendMessage"
            Grid.Row="1"
            Content="Send message"
            Click="SendMessage_Click"
            MouseEnter="SendMessage_MouseEnter"
            MouseLeave="SendMessage_MouseLeave"
            />
  </Grid>

</Window>

Testing layout is represented by a standard WPF Grid panel. Panel consists of two rows. First row occupies the most of the free space (Height=”*”) and the second row takes the Height enough to display a “Send Message” button. First row in this case serves a placeholder for the control being imported from MEF catalog.

Additionally “Send Message” button will raise three events “Click”, “MouseEnter”, “MouseLeave” that will take part in the testing process.

4. Code behind

  public partial class Window1
    : Window, INotifyImportSatisfaction
  {
    CompositionContainer _container;
    IEventAggregator eventAggregator = new EventAggregator();

    [Import("EventViewer")]
    private TextBox viewer = null;

    public Window1()
    {
      InitializeComponent();
      Compose();
      this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    private void Compose()
    {
      _container = new CompositionContainer(
        new AssemblyCatalog(Assembly.GetExecutingAssembly()));

      CompositionBatch batch = new CompositionBatch();
      batch.AddPart(this);
      batch.AddExportedObject<IEventAggregator>(eventAggregator);

      _container.Compose(batch);
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {
      PostUserMessage("Window loaded...");
    }

    #region INotifyImportSatisfaction Members

    public void ImportCompleted()
    {
      if (viewer != null)
      {
        this.LayoutRoot.Children.Insert(0, viewer);
        Grid.SetRow(viewer, 0);
      }
    }

    #endregion

    void ButtonClick(object sender, RoutedEventArgs e)
    {
      PostUserMessage("Button clicked...");
    }

    void ButtonMouseEnter(object sender, MouseEventArgs e)
    {
      PostUserMessage("Mouse entered button..");
    }

    void ButtonMouseLeave(object sender, MouseEventArgs e)
    {
      PostUserMessage("Mouse left button..");
    }

    void PostUserMessage(string text)
    {
      eventAggregator
        .GetEvent<UserMessagePostedEvent>()
        .Publish(new UserMessage(text));
    }
  }

First you initialize the CompositionContainer (for more details on CompositionContainer please refer the MEF’s Programming Guide). Also you insert EventAggregator into the container as an IEventAggregator export and declare a placeholder variable for importing an “EventViewer” external part (as a TextBox).

Upon InsertCompleted event the imported Event Viewer control is injected into the main window layout (first row that occupies most of the free space).

Finally I’ve declared three event handlers for the button control that raise a simple event by means of a helper method called PostUserMessage.

After running an application you will be able to see that external part successfully wires the EventAggregator events and is able processing messages send by external components.

WPF sample with EventAggregator assembly can be downloaded here

WPF PropertyGrid goes BETA

January 29, 2009 Denis Vuyka Leave a comment

Today WPF PropertyGrid Control left the CTP state and went Beta. During the preview period I got a great number of emails with feedbacks, most of the sufficient changes were driven by the community rather than my own demands. A lot of features are still in progress but overall behavior gets more and more stable.

Here’s how it looks like for the moment (default out-of-box theme is used for the screenshots)

1. Categorized Properties View

Categorized Properties View

2. Alphabetical Properties View

Alphabetical Properties View

Besides Inline templates each property value editor supports “Extended” editors. I’m trying to avoid using modal dialogs where possible, the “Extended” editors are shown within the Property Grid control in a separate property tab.

Entering the Extended editing mode:

Entering Extended editing mode

Editing property value within a separate property tab that can be closed at any moment:

Separate Editing Tab

Closing Extended tab and returning back to Categorized view

Closing Extended Tab

Each property tab can contain really Anything developer wants. Even the default property views can be dropped in favour to custom implementations. 

I would like to mention that this can be regarded as a unique feature as neighther Windows Forms Property Grid nor Expression Blend property editor provides separate tabs for editing property values. I plan moving collection editors and other complex values to the same approach instead of putting the object member hierarchy into the endless tree.

Hope the community will like this feature.

Stay on the line for more news…

Categories: WPF Tags: , ,