Sharing Resources in WPF/SL

I just stumbled across the problem where I wanted to share a specific Path element between different Buttons as their Content. I declared the Path in a ResourceDictionary

    <Path x:Key="MinusPath"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch"
          Data="{StaticResource MinusData}"
          Stretch="Fill"
          Stroke="Red"
          StrokeThickness="3" />

and referenced the Path in each Button with

<Button Content="{StaticResource MinusPath}"/>

This works for exactly one Button but not for more. You will get a XamlParseException with an InvalidOperationException as its InnerException. The problem is that you need a new Instance of the Path for each Button.

It actually took me quite a bit until I googled a solution for the problem and the solution is shockingly simply. You just need to add x:Shared=”false” to the Path declaration

    <Path x:Key="MinusPath"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch"
          Data="{StaticResource MinusData}"
          Stretch="Fill"
          Stroke="Red"
          StrokeThickness="3"
          x:Shared="false" />

Up to now I just didn’t know about this x:-Attribute because it is missing in Intellisense.

Posted in Silverlight, WPF

MVVM Dialogs with Caliburn.Micro

Background

In every applications life there comes a time when you need to show some kind of message to the user. Be it a question whether he really wants to delete something or a simple message that says that some operation was successfull. The most simple way to do that is the good ol’ MessageBox.Show() with its zillion overloads.

MessageBox.Show("Foo", "Bar", MessageBoxButton.OKCancel);

But in the shiny MVVM World , poluting your ViewModels with MessageBoxes is usually frowned upon since it breaks a lot of stuff, especially automated unit testing and theming.

You can find quite a lot solutions about how the ‘MVVMize’ MesasgeBoxes and dialog screens in general. Most of them involve wrapping the MessageBox.Show() in some kind of IService, setting up some kind of event infrastructure and other funky stuff. Surprisingly, all of those solutions completely ignore the first M in MVVM, namely the Model, and none really tackles the problem at its heart.

Continue reading

Posted in C#, Caliburn.Micro, CMContrib, Silverlight, WPF

Handling Errors in Caliburn.Micro’s IResult – Part II

Preface

In my last post I gave two possible approaches and a preview of my final solution for handling errors in IResults. The syntax for my final solution was

yield return new ProcessDataResult()
		.Rescue().With(coroutine: IORescue)
		.Rescue().With(coroutine: GeneralRescue);

This means that

  • whenever the result completes with an error of type IOException, the IORescue coroutine is executed
  • whenever the result completes with any other error, the GeneralRescue coroutine is executed

So the behaviour of the Rescue is similar to a try/catch block

try {}
catch (IOException e) { //IORescue }
catch (Exception e) { //GeneralRescue }

Continue reading

Posted in C#, Caliburn.Micro, CMContrib

Handling Errors in Caliburn.Micro’s IResult – Part I

The Problem

One of Caliburn.Micro’s nicest feature is, hands down, the concept of Actions. In that concept the IResult plays an important role, especially when using Coroutines. If you don’t know about them, you should definately read up on them here first.

So, let’s assume we are executing a Coroutine which first shows a loading screen to the user, then starts processing a lot of data and finally hides the loading screen once the processing is finished. Since the processing is also likely to fail for whatever reason we want to handle the error by executing a Rescue Coroutine.

public IEnumerable ProcessData()
{
	yield return new BusyResult("Processing...");

	yield return new ProcessDataResult();

	yield return new NotBusyResult();
}

The implementation of those results is irrelevant since we want to have a look at how we can handle the error during the processing in a nice (reusable) way.

Continue reading

Posted in C#, Caliburn.Micro, CMContrib

Caliburn.Micro feat. AvalonDock II: Save/Restore Layout

One of the most convient feature for the user is to save the layout of the different widgets in your app, especially if you can arrange them as nicely as with AvalonDock. Luckily, the DockingManager already supports this feature, so basically all we have to do is store the list of all conducted items of the conductor and the widget layout in the filesystem when the app closes. When the app is started again we restore the list of conducted items and in doing so the dockable contents of the DockingManager (which must have the same name as before). Then we tell the DockingManager to restore the layout and we are done.

Continue reading

Posted in C#, Caliburn.Micro, WPF

Caliburn.Micro feat. AvalonDock I: Conductor and View

AvalonDock is a fancy, open source tab control for WPF which i wanted to use in one of my clients projects because it supports save/restore layout. Unfortunately, binding the avalondock control to your view model isn’t as easy as it is with the standard wpf tab control. Hence i googled a bit and found this article in the AvalonDock documentation and a blog entry which deals with the problem but both didn’t really solve the problem. What i needed was a notification mechanism for the gui when the conductor changes (or closes) its ActiveItem and vice versa, i.e. a two-way binding.

Continue reading

Posted in C#, Caliburn.Micro

Automatic Auditing with NHibernate

Many business applications require that we track who created or changed an entity, etc. There are basically two ways to store the audit data . The first one is to store the audit data directly with your entity and the other, more complex way is to create an audit log which stores all important changes to the entities. Since we are only interested in storing who created/modified an entity, we will use the first approach. Although you can find some implementations for this approach on the web, none of them meet all requirements i have.

The requirements are:

  • Fine-grained control about what we want to audit for each entity type
  • Automatic (fluent) mapping of the audit properties
  • Setting the audit data automatically on each insert/update
  • Easily change how the username and date is retrieved

Continue reading

Posted in Fluent NHibernate, NHibernate