Categories
Programming WPF

There is no ViewModel

I’ve noticed a strong trend of using a ViewModel suffix for classes in the ViewModel of Silverlight and WPF applications.
In practice, I discourage people from using the ViewModel suffix because it’s not logical, and tends to lend to more confusion than understanding. I’ve been trying to track down the source of the suffix to figure out if it’s an official naming guideline or just used in examples to clarify to which set or layer a class belongs. I saw this mentioned a few times as the “John Gossman” naming pattern, and I wondered if that were the case. When I contacted John, he expressed that it was, in fact, just a convention used to clarify an example and not intended as a recommendation.
The ViewModel is really a layer containing a set of classes, no one class can really be “the” model (ignoring façades for now). The problem I’ve run into is that people get confused as to whether the ViewModel is a class or is a set of classes, and when I talk about “the ViewModel” invariably people think I’m talking about a particular class, I have to un-train them a bit in order to clarify what we’re talking about. The other side-effect I have seen is that people tend to overlook things like the built-in converters that are often a better alternative than adding a dedicated class in the ViewModel layer.
A class is in a ViewModel (or Model) in the same way that a person is in a Group. You wouldn’t call a particular person in the group a MaxxGroup though, because a member of the set isn’t the set. It might be a little pedantic, but then I don’t think I’d be a software architect if I weren’t a little pedantic…
I also generally put my ViewModel classes in a folder/assembly/namespace, but tend to name them with a suffix that indicates the pattern they are generally following. ViewModel classes tend to actually be bridges, wrappers, façades, and adapters (much like Collection has a CollectionView in the ViewModel which adds viewstate to the Collection) but the point is that it’s more important to describe what the class actually is, not where it is.
Without this understanding, there is a de facto assumption that “ViewModel” classes should be created for every class in the model, an idea that the ViewModel layer is a necessary abstration rather than an optional layer to adapt classes that are unfriendly to the View. In many cases, that’s exactly the wrong thing to do. My approach to explaining how, in practical terms, to approach the MVVM model with WPF/Silverlight goes something like this:

  1. Bind to the object in the model. Some objects will bind just fine. But, If the object isn’t binding friendly…
  2. Use a built-in converter to convert the object to and from something more binding friendly,
  3. If you just need to get past a method call to something with properties, use an ObjectDataProvider,
  4. Write a class in the ViewModel and use a converter or custom provider class to adapt the class between the layers.

As an example, in a recent WPF application I wrote, I created two classes in the ViewModel: a DirectoryView and a FileView. I found that I wanted these classes to adapt the binding-unfriendly (because of method calls, primarily) DirectoryInfo and FileInfo classes. (If the binding system handled methods, I could have used the Info classes directly and not added classes to the ViewModel.)
The pattern goes something like this:

public class DirectoryView
	///Convert GetFiles() to Files enumerable on DirectoryInfo
	///and return bindable FileViews from FileInfo instances.
	public IEnumerable Files
	{
		get { return dirInfo.GetFiles().Select(file => new FileView(file)); }
	}

With this approach, you can write a FileSystemProvider that generally follows the XmlDataProvider/ObjectDataProvider patterns, which allows the developer to create and set up a static resource in XAML to browse a filesystem in XAML-friendly DirectoryView and FileView classes.
So in terms of a pattern, I would say this, “If you have a set of hierarchical classes in the domain that are method-heavy, write a view adapter that converts property calls to method calls, and wrap the results in further view adapters. If there is no hierarchical force in play, just use a ValueConverter to wrap and unwrap the class.”
At this point, we need to advance the discussion beyond the basics of the MVVM pattern and start creating a set of patterns and vocabulary for the types of classes in the ViewModel (adapter, bridge, provider, view), and guidance like the above on when and how to create them. Sort of a “Design Patterns for MVVM” for developers to draw from, and to identify which forces are observed to guide the solution.

Categories
Programming WPF

Using Windows in WPF

On our Manning book forum, I received a question from trifonius regarding the use of multiple windows in WPF:

First of all, I’d like to compliment the authors with the book. It’s a great read, thorough explanations and clear examples.
I’m working on an application that needs to be able to edit data as well as showing reports on data. Since these two interfaces are very different I think I need multiple windows in this app, available from a menu or something.
Since there is no mention in the book of multiple windows, I wonder whether this is the recommended way to go. Is it advisable to use panels with controls and set their visibility (or something like that) instead? Seems like a bit of a hassle to me.
If it is fine to use multiple windows, how can I display them from selecting a menu item?
Thanks

Thank you for the compliments! It’s great to hear that our work is proving to be beneficial. It’s the result of a lot of blood, sweat, and tears, and mostly blood… 🙂
It’s fine to use multiple windows in a WPF application. For various reasons we had to cut some material, including drag and drop and multiple windows, but that should not be interpreted as a recommendation against them. It’s true that some people are very adamant about not having multiple windows, but it really comes down to what problem you are trying to solve, who are your users, and what your application does.
Working in a single window was a limitation of web development for a long time, and it forced web developers to think of new approaches to solve problems typically addressed by windowing operating systems. This resulted in some very nice UI approaches, but also resulted in what I see as an over-correction where a group of those people came to view windowing in general as “evil.” One of the more effective counter arguments comes from multiple monitor configurations.
I have used multiple monitors for years, and found the productivity of having 2 or more screens is unquestionable. An application that does not allow you to open multiple windows is fundamentally incapable of taking advantage of such a configuration, so if you have anything in your application that might be able to make better use of monitor real estate, definitely look here. Think about the XAML Designer itself in Visual Studio. If you have two monitors, wouldn’t it be great to open the XAML window on one monitor, and the full design surface on another? You can’t now, but this strikes me as a major omission. (The poor man’s approach is to split the designer and xaml vertically, then stretch the window across both monitors and you get nearly the right effect).
That’s enough pontificating (for now) so on to your question…
On the context menu of your WPF Application project, you can select “Add/Window…” to create the Window XAML and code. For the sake of this example, I created a new project and left the Window1, and created a new Window called “DataEditWindow”
Add a CommandBinding and a both a Button and MenuItem to demonstrate the call:

    
        
            
        
        
            
                
                    
                
            
            
        
    

In the cs file, a couple special notes apply:
If you want to give the new window a particular DataContext for binding, you can set it here. Also, the Window should know who its parent is, so always set the Owner property to the Window you are launching from. In this example I’m binding to the ApplicationCommands.New command, but you could just as easily bind it to a control event or RoutedEvent (I tend to recommend thinking and binding in terms of commands):

private void new_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}
private void new_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var window = new DataEditWindow()
        {
            DataContext = DataContext,
            Owner = this,
        };
    bool? result = window.ShowDialog();
    if (result.HasValue && result.Value)
	MessageBox.Show("Ok clicked");
    else if (result.HasValue && !result.Value)
	MessageBox.Show("Cancel clicked");
    //window.Show(); // Show window, but do not wait
}

The next bit is a choice. If you want the window to be model and block all operations in the parent window (a print dialog is a good example where modal makes sense), then use the window.ShowDialog() method. If the window is more of a palette and you want to allow the user to be able to continue using the application, use the window.Show() method. Too many modal windows can be frustrating, but attempting to handle state changes can also hurt.
Since window.Show() is the simple case, this is what you’ll need to add to the child window for handling the DialogResult. In the XAML, we’ll need some buttons to let the user indicate their intent with the dialog:
DataEditWindow.xaml:

    
        
            
            
        
    

Then you will need to set the DialogResult before you close the window so that the caller can decide what to do. This way, the parent window can decide whether to take the action or not. Note that you will get an exception if you try to set DialogResult, but the window was opened with window.Show(), so if you want this window to be dual purpose, you will have to handle both cases.
DataEditWindow.cs:

private void Ok_Click(object sender, RoutedEventArgs e)
{
    DialogResult = true;
    Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
    DialogResult = false;
    Close();
}

In an application I would tend towards the approach of creating a DataTemplate, and I would create a generic WPF Window class that is simple a ContentControl. Set the DataContext of the Window to the object you want to edit, and let the template system pull up the right template for the editor. Something like this:


    
        
        
    
    
    

With this approach, you can choose to show the editor in-place or show it in a window with very few code changes.

Categories
Programming

Exception Handling 101

I hate buggy software. However, as a developer, I know how difficult it is to write bug-free software and so I am always looking for new ways to learn how to write better software. One of those ways is exception based programming. Sadly, exceptions are often glossed over in samples and books so exception anti-patterns tend to propagate.
Take a look at the following code…

public void HorrifyingMethod()
{
	try
	{
		Cursor preCursor = Cursor.Current;
		Cursor.Current = Cursors.WaitCursor;
		DoSomething();
		DoSomethingElse();
		try
		{
			Log.Write("I did something");
		}
		catch {}
		Cursor.Current = preCursor;
	}
	catch (Exception ex)
	{
		if (ex.Message == "Failed")
			throw ex;
		else
			Log("Something failed", ex);
	}
}

There’s so much wrong with this method it makes my skin crawl. Let’s start with the obvious:
Catching the base exception type
There aren’t a lot of cases where this is ever justified. When you catch an exception, you are effectively stating that you understand the nature of the failure, and you are going to resolve the problem (logging, by the way, is not resolving the problem). Our nested try/catch block may as well say “if the server caught fire, I’m just going to ignore it.” When you write an exception method, it is helpful to say to yourself, “The managed runtime exploded, therefore I am …” and say what your catch block does. If you find yourself saying something like “The managed runtime exploded, therefore I am returning the default value” you can see how problematic this really is.
Discriminating on exception data rather than exception type
Exceptions should describe the nature of the problem, not where it came from. Every exception already comes with a stack trace so we know where it came from. A good exception is something like “TimeoutException” rather than “MailComponentException” If you find yourself commonly digging through exceptions to determine what exactly went wrong, you are using a poorly designed library. If you are throwing exceptions, use an existing exception class if it fits the problem, or write a new class that describes the problem. The exception type itself is the filter used for catching, so it’s important for exceptions to describe the nature of the failure.
Re-throwing a caught exception from a new catch block
There are times when you might catch an exception, and after doing some programmatic investigation decide that you can’t actually handle it and you need to rethrow it. Never rethrow the same instance that you caught in the catch or you’ll wipe out your stack. The correct way to rethrow a caught exception is just a single “throw;” statement with no variable.

public void CorrectRethrow()
{
	try
	{
		SomeMethod();
	}
	catch(Exception ex)
	{
		if (!ex.SomeProperty)
			throw;
	}
}

Eating the exception
This is probably by far one of the worst offenders. Exceptions work well because they are an opt-out method of detecting abnormalities rather than past “opt-in” methods such as errorcodes. Eating exceptions is rarely correct. If you are developing a library for use by other developers, you should not be making decisions for them with regard to exceptions. Always throw the exception to the library user so that she can handle it as she sees fit. The HorrifyingMethod() code shows two exception eating problems: The inner try/catch block is catching both managed and unmanaged exceptions, and completely hiding the fact that anything went wrong. This is all too common, and contributes to bugs, failures, and strange side-effects with nearly impossible to trace causes. The outer block logs the exception, making a token gesture of “handling” it. Imagine this method being called from a button click event. The user keep smashing the button, the program continues to fail to execute the procedure, and somewhere an obscure log file is recording all the detail. Logging an exception is not handling it.
(Note that if you do have more than one try/catch/finally in a method, your design is probably screaming for an ExtractMethod refactoring. Your method is almost certainly too large if there is a need for more than one)
Lack of a finally block to ensure consistency of changes in the method
There should be far more try/finally blocks in your code than try/catch blocks. In order to write exception-safe code, anything in a try block must be reverted by a finally block to leave the application in a consistent state. When an exception was thrown in Visio, it would bring up a dialog box saying that the application state was inconsistent and advised you to restart the application. This is decidedly not okay in the .NET world.