» Publishers, Monetize your RSS feeds with FeedShow: More infos (Show/Hide Ads)
My current project has stringent requirements across the board, including that of a highly consistent coding style. This is completely understandable because the client will be taking over maintenance and long-term support sometime after we’ve shipped. As such, they want to feel comfortable that their developers won’t be handed a steaming pile of code poo to polish.
One of the tools I thought might help us with this problem is StyleCop. This tool can analyze your code and flag any issues related to style. My initial suspicion was that StyleCop would annoy the heck out of me in about 10 seconds flat. It would whinge about missing file headers, the number of blank lines between code blocks, and even missing API documentation on private members. And it did do just that.
But something strange happened after a while: I stopped caring.
But not in a bad way. I just let the tool make these micro-decisions for me and instead concentrated on more important things like – you know – making the product actually work. If it told me I needed a blank line between my property getter and setter, I just did it – no questions asked. There was no nagging worry that I would do it differently elsewhere, or that some future developer on the project would, because the tool simply wouldn’t allow you to.
I’ve been able to get StyleCop integrated to an extent that I am very happy with:
- It runs every time I build, whether it’s on my machine or the build machine. And it does not need to be installed on the developer’s machine (or the build server)
- Any problems StyleCop reports prevent the build from succeeding (i.e. any problems are errors, not warnings)
- Less important projects are excluded from StyleCop altogether, or have relaxed rules (such as for unit test projects, which don’t need API documentation)
- Modifications to StyleCop settings are stored in central settings files and shared across projects. For example, I have a TestProjectSettings.StyleCop file, which contains settings for unit and integration test projects. If I disable a rule for one test project, it is disabled for all of them
The intent of this post is not to help you set StyleCop up with MSBuild. There are other resources out there that show you how to do that. I’m more interested in encouraging people to try this tool out. The more people that use it, the more it will be improved. And there is plenty of scope for improvement, as I’ll discuss shortly. If you’ve held off trying out this tool because you had bad experiences with it earlier in its short history, or because you think it has little to offer, perhaps it’s time to rethink.
So, what are the problems I’ve had using StyleCop? The biggest problem is that it’s lazy. It will happily report style problems to you any day of the week – even Sunday – but it refuses to lift a finger when it comes to rectifying said problems. This can be very irritating at first, but over time I have found myself preemptively and reflexively avoiding StyleCop’s wrath by writing code that conforms more and more to the default rule set.
The next problem is that of the default rule set. In adopting StyleCop I made it quite clear to my client that doing so implies either accepting the default rules, or spending a significant amount of time writing custom ones (time I don’t have). I can almost guarantee you won’t like all the default rules. Some of them will make you cringe, whilst others may make you downright furious. Of course, you can disable or tweak those rules that really get your goat.
Finally, StyleCop is particularly frustrating when you’re just wanting to try out a piece of code quickly in your project. There’s no built-in mechanism to demarcate a block of code as temporary and exempt it from style checks. Undef’ing the CODE_ANALYSIS symbol seems to do nothing, and SuppressMessage does not have any wildcard support. Therefore, you either need to move your scratch code into a temporary project, or waste time placating StyleCop.
UPDATE: As noted by wekempf in the comment below, you can wrap experimental code in a region with “generated code” in its name. This works even when you have the disallow all regions StyleCop rule enabled!
But for all its warts, I still feel somewhat liberated by StyleCop. No longer do I worry about whether I have the correct spacing, line breaks, or bracket placement in my source. I let the tool worry about that for me. And I feel as though spending the extra brain cycles on more important concerns is a win for both myself and my client.
Note that I am the only .NET developer on my project at the moment, so I can’t really comment on how well this would work with a team. I can’t really see it being an issue if everyone agrees that no rules should be disabled or suppressed without due justification and discussion. Some developers are sure to balk at the idea of having to conform to a particular style, but that’s only because it’s not their style. Heck, I was hesitant at first to make dramatic changes to my style (I prefer tabs, for example), but I quickly adjusted when I saw the benefits of the tool.
So next time you’re embarking on a new project, consider integrating StyleCop right from the get-go. The short term may be painful, but I think you’ll appreciate the decision in the long term.
Seems obvious when you think about it, but I thought it worth pointing out all the same. If you’re trying to up the ante on your keyboard settings inside a VM, be aware that their effect will be limited by the the keyboard settings on the host.
So if you set your VM’s keyboard to repeat crazy fast:
But your host is set to crazy slow:
The effective result in your VM is crazy slow. That’s because the host will only be passing on keyboard events to the VM in crazy slow mode, so the keyboard settings in the VM are essentially moot.
Having a job in IT can sometimes be a curse. To mere mortals, the whole world of things that go beep is lumped together in a box labelled “voodoo”. Any issue even remotely related to computers can be directed your way. The typical geek probably finds themselves having to deal with document formatting problems, faulty mobile phones, and friends who can’t remember their email address. Can you imagine asking a cardiologist to examine your foot? No? Me neither.
My Mum – who runs Ubuntu – asked me for some help with her webcam the other day and I felt compelled to help her because:
- She’s my Mum.
- I got her onto Ubuntu in the first place and set it all up for her.
- She’s my Mum.
The problem is that she lives in the sleepy town of Adelaide whilst I live in London, some 16,000 kilometres away.
Now, if we were using Windows I’d have used a service like CrossLoop to remote onto her machine†. I’ve used it in the past to help my sister with her machine, and it was very good. Basically, CrossLoop works by acting as a middle-man between the two machines, so instead of connecting directly to each other, they connect to a CrossLoop server. This helps get around all the issues with firewalls and ports that the average computer user shouldn’t have to understand. Of course, it implies that you trust CrossLoop not to snoop on any data exchanged between the machines.
Alas, CrossLoop is Windows and Mac only‡ – no love for the world of Linux. Moreover, I couldn’t find an alternative service at all for Ubuntu. To that end, I set about looking for something that would allow me to help my Mum. My requirements were simple enough:
- Must be secure.
- Must require no effort by my Mum except running a script. And when I say “no effort” I really mean that. Requiring any kind of router configuration or software configuration, for example, would be a deal-breaker. If I asked my Mum to open a port, she’d tell me it was too early in the day to drink (yes, even if it was 9PM).
After some reading and testing on my end, I settled on a solution using the most excellent SSH protocol. The key for me was SSH’s ability to set up a reverse connection. This allowed me to set up the SSH server and configure my router to do the port forwarding. Then I provided my Mum with a script that simply:
- Kills any resident VNC session.
- Starts up a new VNC session.
- Sets up a reverse SSH tunnel to my machine, forwarding traffic on my port 9999 to the relevant VNC port on her side (5901). Having your own DNS entry helps here, but isn’t strictly required if you don’t mind validating the port in the script every time you use it (again, not an option for my Mum).
Once she runs that script, I can run a VNC client and connect to port 9999 on my local machine. By virtue of the SSH tunnel, I’m actually connecting to port 5901 on her machine, which is the VNC session. Magic!
The whole setup can be depicted graphically as follows (click to enlarge):
So there you have it. When my Mum has issues, she double-clicks a file on her desktop, enters a password (although you can use keys instead), and I can then connect to her desktop and hopefully sort it out. Now you, too, can provide remote support for your Mum’s Ubuntu installation.
Now all I have to do is fix her foot – I mean, webcam!
† OK, OK, Linux haters – perhaps if my Mum was using Windows the webcam would be working just fine and this whole post would be moot. Instead I might be posting about how I had to rescue her machine from the clutches of malware.
‡ OK, OK, Linux and Windows haters – perhaps if my Mum was using a Mac I’d be able to use CrossLoop and this whole post would be moot. Instead I might be posting about how I had to loan my Mum some money so she could buy milk and bread.
Addendum: I had an issue with the keyboard mappings with VNC. Basically, I would type “abcd” and would get “asdf” on the remote machine. Turns out this is a known issue and I found this blog post on the subject. It was a comment by dcatdemon on that post that helped me:
- Edit your $HOME/.vnc/xstartup
- Put the line "export XKL_XMODMAP_DISABLE=1" before your gnome-session
- Restart vncserver
Note to Self: regarding the actual webcam, I had to recompile and reinstall the driver. When I set up Ubuntu originally for Mum I had to manually compile the driver because there was no built-in support for her webcam. Presumably, the latest kernel update had somehow broken backwards compatibility and the driver was no longer successfully being loaded. So I removed the old .ko driver binary from /lib/modules/kernel*/drivers/media/video/usbvideo/ and then recompiled and reinstalled according to here.
I suppose this may happen after future kernel updates, too. Lucky I have that support script all set up!
I have just released version 1 of Truss, a binding framework for POCOs. Truss allows you to bind together arbitrary .NET objects regardless of your choice of UI platform, or in the absence of a UI altogether.
Amongst its features, it provides support for bindings that use “magic strings” to specify property paths, as well as lambda expressions for compile-time checked bindings. Here’s a very simple example to whet your appetite:
var parent = new Person(); var child = new Person(); var bm = new BindingManager(); //bind the parent's savings to the child's inheritance bm.Bindings.Add(new TypedBinding<Person, Person>(parent, p => p.Savings, child, c => c.Inheritance));
There are a number of scenarios I intend Truss to address, both now and with future enhancements:
- Keeping related view models POCOs in sync with each other
- Keeping related business objects in sync with each other
- Provide a strong alternative to the limited binding support in Winforms, thus facilitating clean MVVM development in Winforms
You can download Truss source, binaries, and comprehensive documentation from here. Please direct any feedback my way.
A while back I answered this question on stackoverflow and have been meaning to elaborate on my answer ever since with a more comprehensive blog post. The question is about how to highlight some text in the UI when the user enters some search text. I thought I’d extend the concept into a clean, generic solution as far as I could and share it here.
My requirements are pretty straightforward:
- Provide a search box in which the user can enter some text.
- Highlight all matching text in the window, regardless of where it appears in the visual tree.
I was able to pull this off to an extent I am satisfied with. See the screenshot to the left. The user can enter some text in the top-right search text box, and then hit enter (or click the magnifying glass). Then all matching text is highlighted anywhere in the visual tree.
After an initial approach that relied on reflection in order to highlight content elements (ugh!), Marlon Grech kindly passed my question about how to do this more cleanly onto Dr. WPF and Jamie Rodriguez, who pointed me in the right direction (thanks guys!).
The basic approach I ended up using is:
- Traverse the visual tree recursively, looking for IContentHosts and DocumentViewerBases. For DocumentViewerBases, extract the IContentHosts corresponding to each page.
- For each IContentHost, search through its HostedElements collection to find any Runs.
- For each Run, inspect its Text to determine whether the search term matches.
- If the search term matches, use some TextPointer trickery to determine the bounding rectangle of the text.
- Use a Canvas to lay out all semi-transparent rectangles on top of the application window, thus highlighting the matches.
There are a few problems that I’m aware of:
- If the matching text spans multiple lines, the bounding rectangle isn’t correctly calculated. You could use IContentHost.GetRectangles to calculate all bounding rectangles correctly, but I just haven’t bothered to do so for the purposes of this post.
- It doesn’t work for all content element hosts, such as FlowDocumentScrollViewer, because they don’t inherit from DocumentViewerBase. I suspect it’s probably not too hard to add support for them, but again I haven’t bothered to do so for this example.
- It’s quite slow when the search term is short and frequently matched (as an example, try searching for “a”).
So the approach isn’t perfect, but this was an experiment more than anything else. I think a real application would want search support more intrinsic rather than relying on a generic mechanism like this. That said, there are bound to be some practical applications of the general technique used here.
PS. You may have noticed a lack of TMNT-related material in my sample this post. Unfortunately, my Windows Home Server recently died, which has prevented me from continuing to watch the series and has let my obsession waver somewhat. A replacement server is due next week, so expect more green reptile-based content soon!
Download Command.cs
Download DelegateCommand.cs
Download DelegateCommandExample.zip
This post is part of a short series I am doing on MVVM infrastructure. In this series, I will share some thinking and code that has helped to produce cleaner, simpler MVVM code in my applications.
Related posts:
- POCOs versus DependencyObjects
- ViewModel
- DelegateCommand
- ActiveAwareCommand
In my last post I discussed my ViewModel base class. In this post I’m going to start showing you some infrastructure around commanding.
WPF's commanding support enables you to hook up UI interactions with code without tightly coupling the two. User actions are abstracted into implementations of WPF’s ICommand interface, which are then associated with controls that implement ICommandSource. Essentially, it's a layer of indirection. The controls in the UI aren't intimately aware of the command logic they are connected with, and the command logic isn't aware of the controls it will be associated with.
When starting out with WPF commanding, you will soon come across the RoutedCommand class. This particular command is yet another layer of indirection, in that its execution logic involves finding something to execute and calling that! Starting with the focused element, it searches up the visual tree for an element that has a matching CommandBinding in its CommandBindings collection. If the RoutedCommand finds a matching CommandBinding, it executes that CommandBinding's Executed delegate.
Routed commands work great in certain scenarios, and are prevalent in WPF. Indeed, the only concrete ICommand implementation that comes with WPF is the RoutedCommand (and its subclass, RoutedUICommand). Unfortunately, this has caused WPF commanding to become somewhat synonymous with RoutedCommands, which is not at all accurate.
The thing is, routed commands are not always a great fit for MVVM development. Typically the logic for your command execution belongs in the view model. For example, suppose you have a CustomersViewModel that maintains a list of CustomerViewModels, and you want to expose a command that deletes the selected customer. The logic for that command should reside in the CustomersViewModel, since it knows best what to do when a deletion is requested.
If you were to use a RoutedCommand, you would then need a CommandBinding somewhere in the UI in order to connect a visual element to the DeleteCustomerCommand. In our example, we would likely stick a CommandBinding in the CustomersView and associate it with the deletion command and methods on the view model. Without the CommandBinding, the RoutedCommand won't find a handler for the command and the Delete button will be forever disabled.
Using routed commands with MVVM ends up being messy, sub-optimal, and requires the view be more tightly coupled to the view model. And in some scenarios, it’s not even possible (I’ll discuss such a scenario in my next post). But the good news is, we don't have to use routed commands. All we need is an appropriate implementation of ICommand – one that is more conducive to MVVM development.
If you think about it, all we really want to do is have a command that – when executed – invokes a method in our view model. And when the command is queried for its executable status, it executes a different method in the view model. To continue our customer example, that command might be associated with a Button in our CustomersView. The availability of the command would be dependent upon the user first selecting a customer (you can't delete a customer if you don't know which customer to delete). The execution of the command might execute a DeleteCustomer method on the CustomersViewModel.
Sound simple? That's because it is! Far simpler than attempting to use routed commands for this scenario.
The command implementation I use is called DelegateCommand, simply because it invokes delegates when executing and querying executable status. Other people have different names for this type of command, the most common of which seems to be RelayCommand. That's fine - call it what you will.
Prism has a DelegateCommand too, which is almost exactly the same as this one. However, the reason I have my own is simply because we don't use Prism in our project†, and it would be a large overhead to pull it in just for the sake of a class or two. Besides, if you're doing a non-composite WPF app, Prism may not be a good fit.
To create a DelegateCommand, you simply give it one or two delegates to use. If you give it only one delegate, the command is assumed to be always available. That is, ICommand.CanExecute() will always return true.
In our CustomersViewModel, we create the DelegateCommand as follows:
_deleteCustomerCommand = new DelegateCommand(DeleteCustomer, CanDeleteCustomer);
We then expose the command from a property in our view model:
public ICommand DeleteCustomersCommand { get { return _deleteCustomerCommand; } }
And bind to it in the view:
<Button Command="{Binding DeleteCustomersCommand}">Delete</Button>
It’s as simple as that. The delegates supplied to the DelegateCommand will be invoked at the appropriate times and our Delete button will only be enabled when a customer is selected. You can see all this and more in the download.
Incidentally, DelegateCommand inherits from a base Command class. That’s just to keep the code DRY with respect to other command classes I have, such as the ActiveAwareCommand. I’ll talk about that one in the next post.
† The application in question was built before Prism shipped, elsewise we would be.
Download Command.cs
Download DelegateCommand.cs
Download DelegateCommandExample.zip
This post is part of a short series I am doing on MVVM infrastructure. In this series, I will share some thinking and code that has helped to produce cleaner, simpler MVVM code in my applications.
Related posts:
In this post, I'm going to show you a base class for view models I have imaginatively named ViewModel. This is by no means a complex class, but it's a fantastic time-saver when doing MVVM.
I had a few concerns at the fore-front of my mind when designing this class. Firstly, I wanted it to be extremely simple to use. When inheriting from it, I didn't want to have to worry about implementing specific constructors in my subclass or providing implementations of abstract members. It should be brain-dead simple to extend the ViewModel class.
Secondly, I was concerned about having too many members on the base class. Doing so could make it harder to discern those members of interest when working on subclasses. Essentially, I didn't want a lot of noise in the APIs, because that adds just that little bit of friction that can accumulate into a ball of pain.
Thirdly, I didn't want the class to impose too much on subclasses. They should be granted as much freedom of implementation as possible whilst still providing them with value. For example, subclasses should have the ability to provide their own implementation of equality.
Finally, I wanted to minimize the performance impact of leveraging this base class. I didn't want consumers to have to choose between a good view model design and performance. Ideally, they could have their cake and eat it, too. Of course, I'm not saying you can design your view models as fine-grained as you like without a thought for performance. I'm just saying I wanted to mitigate the risk.
As you'll see from the code, I think it's fair to say these goals have all been satisfied. The attached file includes API documentation, but the small size of the class means I can include it here, sans documentation:
public abstract class ViewModel : INotifyPropertyChanged { private readonly Dispatcher _dispatcher; protected ViewModel() { if (Application.Current != null) { _dispatcher = Application.Current.Dispatcher; } else { //this is useful for unit tests where there is no application running _dispatcher = Dispatcher.CurrentDispatcher; } } [field:NonSerialized] public event PropertyChangedEventHandler PropertyChanged; protected Dispatcher Dispatcher { get { return _dispatcher; } } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { PropertyChanged.Raise(this, e); } protected void OnPropertyChanged(string propertyName) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } }
There are really only two responsibilities taken on by this class:
- Implement INotifyPropertyChanged.
- Provide access to a Dispatcher.
The OnPropertyChanged overrides allow subclasses to easily raise the PropertyChanged event (incidentally, that call to PropertyChanged.Raise is by virtue of my library The Helper Trinity). For example, a subclass might do so like this:
public string Name { get { return _name; } set { if (_name != value) { _name = value; OnPropertyChanged("Name"); } } }
The Dispatcher property allows subclasses to gain access to the current Dispatcher, which makes it much easier to perform work to a background thread and then synchronize the results with the UI. Importantly, a new Dispatcher for the current thread is assigned if no WPF application is running. This makes unit testing much easier as there will always be a Dispatcher available via this property.
So that's it really. Nothing much to it, and that's the way I like it. Next up in this series, we'll start looking at the infrastructure I have around commanding.
This post is part of a short series I am doing on MVVM infrastructure. In this series, I will share some thinking and code that has helped to produce cleaner, simpler MVVM code in my applications.
Related posts:
- POCOs versus DependencyObjects
- ViewModel
- DelegateCommand
- ActiveAwareCommand
If you're leveraging the MVVM pattern in your WPF/Silverlight development, you will quickly be faced with a decision regarding the implementation of your view models: should they be DependencyObjects, or POCOs (Plain Old CLR Objects)? I've seen and worked with applications that use both of these options.
This post is intended to discuss these two options. It certainly won't touch on all issues and nuances of either option, but it will cover the main ones I have found to be problematic. I will order them from least significant to most.
Performance
I was hesitant to even mention this one because I haven't done any measuring and haven’t found it to be a problem at all. There is a theoretical performance benefit to using DependencyObjects for view models for a couple of reasons:
- Lower memory usage.
- Faster binding performance.
The former assumes your view models have a lot of properties, and that those properties tend to take on their default values. WPF’s dependency object system is optimised for this case. Your typical WPF control has dozens or even hundreds of properties, most of which are set to their default value. Extra memory is only used by properties if they take on a non-default value. If your view models follow a similar pattern then you might get some memory usage benefits from using DependencyObjects. But I'd also be questioning your view model design if that was the case.
The second point is more relevant, since the primary job of a view model is to provide properties to which the view can bind. WPF's binding system supposedly performs better when binding to DependencyObjects than to CLR properties. That may well be the case (again, I haven't measured), but the difference must be negligible because this has not proven to be a problem for me thus far.
Property Change Notification in a Related View Model
Suppose you have two view models that are related. For example, a ParentViewModel and ChildViewModel. Let’s say that the ChildViewModel has a reference to a ParentViewModel. When the Savings property on the ParentViewModel changes, we want to update the Inheritance property on the ChildViewModel. Using DependencyObjects as view models, we can simply use data binding to achieve this:
//this code is in the ChildViewModel constructor var binding = new Binding("Savings") { Source = parent}; BindingOperations.SetBinding(this, ChildViewModel.InheritanceProperty, binding);
Using POCOs we need to do a little more work. Typically your POCO view models will implement INotifyPropertyChanged, so the code would look more like this:
//this code is in the ChildViewModel constructor parent.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Savings") { Inheritance = parent.Savings; } };
Neither of these options is particularly appealing to me, but the binding approach with DependencyObjects is more flexible and less typing. Both suffer from magic strings ("Savings", in this case).
I recognised this as a problem with POCO view models a while back and have been busy working on a library that solves it. To whet your appetite, using my library would allow you to do this with any POCOs:
//this code is in the ChildViewModel constructor var binding = new TypedBinding<ParentViewModel, ChildViewModel>(parent, x => x.Savings, this, x => x.Inheritance); bindingManager.Bindings.Add(binding);
Note the strongly-typed binding using lambda expressions. Note also that I'm planning an even terser, fluent interface. Something like:
bindingManager.Bind(parent).Property(x => x.Savings).To(this).Property(x => x.Inheritance);
Serialization of View Models
Sometimes you will want to serialize your view model. For example, you might want to implement the IEditableObject interface so that changes to your view model can be rolled back. An easy way to do this is to serialize a snapshot of your view model and then roll back if necessary:
[Serializable] public class MyViewModel : IEditableObject { [NonSerialized] private object[] _copy; public MyViewModel() { Name = string.Empty; } public int Age { get; set; } public string Name { get; set; } public void BeginEdit() { //take a copy of current state var members = FormatterServices.GetSerializableMembers(GetType()); _copy = FormatterServices.GetObjectData(this, members); } public void CancelEdit() { //roll back to copy var members = FormatterServices.GetSerializableMembers(GetType()); FormatterServices.PopulateObjectMembers(this, members, _copy); } public void EndEdit() { //discard copy _copy = null; } }
This works fine for POCO view models, but not so for DependencyObjects. Recall that for an object to be serializable (and I'm talking strictly about IFormatter-based serialization here), it and all its subclasses must be marked with the Serializable attribute.
DependencyObjects are not marked as serializable.
Incidentally, you might instead follow the pattern where you wrap your data inside a serializable struct and just serialize/restore that struct instead of the view model itself. That works great for POCOs, but – yet again – you will run into headaches if you use DependencyObjects.
And there are other reasons you might want to serialize your view model. Perhaps you want to clone it. Or perhaps you want to save certain view model objects over application restarts. DependencyObject-based view models will cause you grief when this need arises. Basically, your only option is to implement serialization surrogates, or use a non-IFormatter-based serialization mechanism.
Equality and Hashing
It is often useful to compare view models for equality, or stick them in a dictionary. For example, suppose you have a ReportsViewModel that is responsible for managing and exposing a set of ReportViewModels (note the plural versus singular in those names). Each ReportViewModel contains the name of the report, the parameters to the report, and the results of its execution:
Now suppose you'd like to cache report executions. If the user runs the same report with the same parameters, you'd like to just give them the existing results. To achieve this, you'd naturally attempt to override the Equals() and GetHashCode() methods in the ReportViewModel class (and implement IEquatable< if you're thorough). But if the ReportViewModel>ReportViewModel class inherits from DependencyObject, you'll find that you can't.
The DependencyObject class overrides and seals both the Equals() and GetHashCode() methods.
This inability to redefine equality in your view models is both annoying and limiting in certain scenarios. There may be ways around the problem. For example, you could implement a class that implements IEqualityComparer<ReportViewModel> and use it where appropriate. However, this can quickly lead to a mess and anti-DRY code base.
Of course, if your view model is a POCO, it won't suffer from this problem. You'd just provide the most appropriate implementation of equality inside your view model class.
Thread Affinity of View Models
One of the responsibilities your view models will typically take on is that of doing heavy work on a background thread. For example, suppose you have a refresh button in your UI that causes a heap of widget data to be loaded from the database and displayed in a list. You'd hardly want the UI to hang while the database access is taking place, so you decide to put the work in a background thread:
public class MyViewModel { //this gets called when the user clicks the refresh button - we'll worry about how that happens in a later post public void LoadWidgets() { //do the heavy lifting in a BG thread ThreadPool.QueueUserWorkItem(delegate { var widgets = new List<Widget>(); //pretend I execute a database query here, would you kindly? var dataReader = command.ExecuteReader(); while (dataReader.Read()) { widgets.Add(new WidgetViewModel(dataReader["Name"])); } //now we have all our widgets read from the DB, so assign to the collection that the UI is bound to Dispatcher.Invoke(delegate { Widgets.Clear(); Widgets.AddRange(widgets); }); }); } }
All we're doing here is doing as much work on a background thread as we can. Only at the last step do we switch to the UI thread to update the collection that the UI thread is bound to (and with the right infrastructure, even that would be optional).
Again, this is great for POCO view models, but falls flat on its face for DependencyObjects.
A DependencyObject has thread affinity - it can only be accessed on the thread on which it was created.
Since we're creating a bunch of WidgetViewModels on a background thread, those view models will only be accessible on that thread. Therefore, as soon as the UI thread tries to access them (via bindings) an exception will be thrown†.
The only option here is to construct and populate each view model on the UI thread. This is ugly, error-prone, and can negate much of the benefit of doing the work on a background thread in the first place. If we need to create many view models, suddenly the UI thread spends much of its time constructing and initialising those view models.
Code Readability
You'll notice that all of these problems can be worked around, and I don't dispute that. However, all those workarounds result in an incomprehensible mess of code. One of the most important qualities of code is its readability. Using DependencyObjects as view models causes an explosion of supporting code and workarounds that obscure the intent of the code. What's more, all these workarounds gain you . . . nothing.
To me, this is the final nail in the coffin for DependencyObjects as view models. I want my view models to be as readable and maintainable as the XAML I get from using MVVM in the first place. Rather than sweep The Ugly from the view to the view model, I'd much prefer to banish it entirely.
Conclusion
I think the advantages of POCO view models over DependencyObject view models are clear and convincing. Moreover, the disadvantages of using POCOs are practically zero. As such, I always use the POCO option in my projects. That said, all the problems I mentioned can be worked around, and you may have a convincing argument to do so (please let me know in the comments if you do). But, for the here and now, I will be sticking with POCOs for my view models.
In the next two or three posts, I will be sharing some infrastructure I have put together for MVVM applications, starting with a base ViewModel class.
† Note that WPF does do some auto-marshalling for us with simple properties. However, it cannot automatically marshal changes to collections, so you will inevitably end up wanting to create non-trivial DispatcherObjects on the UI thread.
This post is part of a short series I am doing on MVVM infrastructure. In this series, I will share some thinking and code that has helped to produce cleaner, simpler MVVM code in my applications.
Related posts:
- POCOs versus DependencyObjects
- ViewModel
- DelegateCommand
- ActiveAwareCommand
In my last post I discussed the DelegateCommand, which allows you to associate a WPF command directly with logic in your view model. In this post I am going to talk about the ActiveAwareCommand, which does exactly the same thing, but it enables you to widen the scope from which the command is used.
The DelegateCommand works great when the command source (such as a Button) has a one-to-one relationship with the view model. For example, recall the customers example from the previous post (see right). The Add and Delete buttons are defined in the CustomersView. Since the CustomersView has a one-to-one relationship with the CustomersViewModel, the Buttons also have a one-to-one relationship.
But suppose we wanted to change the Add and Delete buttons to MenuItems, and re-use those MenuItems across multiple views. Essentially, we want to change the one-to-one relationship between command source and view model to a one-to-many relationship. With DelegateCommands, the MenuItems would be intimately tied to a particular view. Therefore, the best effort would result with multiple Add and Delete entries in the Menu – one for each view that supports adding and deleting items. We’d have to distinguish the MenuItems with unique headers, such as “Add Customer” and “Add Order”. Obviously, that would result in a horrible user experience.
ActiveAwareCommand provides a solution to this little dilemma by maintaining a list of potential targets for the command, and only interacting with the active target (if there is one). Each potential target is an implementation of IActiveAware†, and the ActiveAwareCommand uses the IsActiveChanged event on this interface to track the active target. The ActiveAwareCommand belongs to a single view model but maps to any number of command sources, thus fulfilling the one-to-many relationship we seek.
The IActiveAware interface gives you the freedom to use whatever logic you like to determine whether the potential target is active. However, it is likely that you will most often use focus to activate an item. To that end, the FocusActiveAwareAdapter wraps a FrameworkElement and gives you an implementation of IActiveAware whose IsActive property is changed to true when the FrameworkElement gets focus, and false when it loses focus.
Generally speaking, the steps for using an ActiveAwareCommand are:
- Construct an instance of
ActiveAwareCommand, usually as apublic static readonlymember of a view model class. - In your view model class, expose a property that allows the view to provide an
IActiveAwareimplementation to monitor. This property should register and unregister theIActiveAwareimplementation with theActiveAwareCommand. - In your view, pass an implementation of
IActiveAwareto the view model when the view loads. Usually this will involve constructing an instance ofFocusActiveAwareAdapterthat wraps the view. - Bind to the
ActiveAwareCommandfrom a shared piece of screen real estate, such as the main menu or application ribbon.
To demonstrate the use of ActiveAwareCommand, I put together another TMNT-related sample project (I’m totally scoping the 2003 era series, like, start to finish at the moment, dudes). In it, the user is able to edit the details of any number of characters in separate tabs. Each character can be saved independently of the others from both the main menu and a tool bar button. Since an ActiveAwareCommand is used for the save functionality, the command is correctly routed to the active tab without any need for manual redirection by the views.
I may have gone a bit overboard with the sample project. I initially started out writing a simpler example, but I found myself wanting something a bit more substantial and real-world. Anyway, feel free to ignore most of the code and just concentrate on the parts pertinent to this post.
I think that about wraps up my series on MVVM infrastructure – for now at least. I hope it has been of some use. I’ve got some other things in mind that I want to blog about, but I’m on leave in Australia through to June. Until then…
† Prism has a similar interface, but it is used for different purposes. Same goes for Prism’s CompositeCommand, which is used to broadcast a command to multiple handlers, as opposed to unicasting only to the active handler.
Kentis is a Tetris clone that I wrote back in 2004 whilst in hospital awaiting the birth of my daughter. It is packaged as a single executable that you can download from either of the links above.
Kentis attempts to remain true to the original game-play, but with an added arcade feel.
If you have any recommendations for how the game can be improved, or if you are able to provide feedback on whether the game works on any additional platforms, please do so in the comments.
The scoring system in Kentis favors those who place blocks faster, and eliminate more lines in one move.
The descent speed of blocks can be increased by pressing the down arrow. A block can be dropped immediately by pressing the space key. The faster you drop a block, the greater your score will be for that move. And the greater your current level, the greater your score will be.
For example, suppose it takes you 1 second to place and drop a block. If you’re on level 1, you will score 12 points. If you’re on level 2, you will score 15 points. If you’re on level 9, you will score 27 points.
For each block you place, you will get an additional score if you clear rows with that block. When clearing rows, the score increases exponentially with the number of rows you clear, and linearly with your current level. For example, if you’re on level 1, you will score an extra 46 points for clearing a single row. But if you clear 2 rows in one move, you will score an extra 58 points, and clearing 4 rows will earn you 202 points. Clearing 4 rows whilst on level 9 will earn you a whopping 1010 points – and that’s in addition to your block score.
Options
Kentis includes a number of options that allow you to challenge yourself further as you increase your skill at playing the game. The table below gives a brief description of each option.
| Option | Values | Description |
| Sound | On Off | Turns sound on and off. |
| Rubbish Rows | 0 – 10 | Determines the number of rows that will be filled with random “rubbish” at the start of each game. Rubbish is colored gray and can be cleared just like any other block color. |
| Rubbish Frequency | 10% – 90% | Determines how frequent the rubbish will be in the rubbish rows. Rubbish is more challenging if it is sparse and covers many rows. |
| Starting Level | 0 – 9 | Determines what level you start each game on. |
| Block Types | Standard Standard + Extra You’re Crazy! | Determines what blocks you will be playing with. The extra blocks are challenging enough. The crazy setting is just . . . crazy. |
| Block Preview | On Off | Determines whether you will be given a preview of the upcoming block. |
| Block Color | Fixed Random | Determines whether block colors are fixed for each type of block, or whether random colors are assigned to each new block. |
Requirements
Operating System: Windows XP (98, 2000, and Vista are as yet untested)
RAM: Minimal (tested on 128MB)
HDD: 2MiB
Graphics/Audio: Pretty much anything
Version History
December 2008 : Updated to use resource compression and cut executable size from over 12MiB to under 2MiB.
January 2005 : Original release on gamedev.net.
WPF’s logical tree is used in providing all kinds of functionality, such as property inheritance and resource resolution.
Yesterday a colleague asked me how to customize the logical children of a control. Basically, he had a control that hosted a collection of child items that aren’t actually visuals. In the XAML, he wanted to be able to bind properties of the children. Kind of like how you can bind to the Height property of a RowDefinition in a WPF Grid control. The RowDefinition isn’t a Visual, but it can participate in binding by virtue of being part of the logical tree.
My initial thought was to override the FrameworkElement.LogicalChildren property, but he had already tried that without success. Altering the logical tree is not something I’ve ever had need to do before. Therefore, I decided to try this out for myself and am recording my findings here.
To test this all out, I created a user control called ArtistsControl that has an Artists property containing a collection of Artist objects. Each Artist object just has a name. The ArtistsControl contains a ListBox that shows each Artist in the collection.
I wanted to address the following use cases:
- Non-bound
Artistdeclaration Artistbound to a property on the owningWindowArtistbound to a property on the currentDataContextArtistwhose name comes from a statically-resolved resource defined in the owningWindowArtistwhose name comes from a dynamically-resolved resource defined in the owningWindow-
Artistbound to a property on the owningWindow, but done in the code-behind setting the source of the binding directly
Aside: The first issue I came up against had nothing to do with the initial problem at all. I wanted to define a user control called ArtistsControl that had a collection property called Artists that could be populated very easily from XAML:
<local:ArtistsControl> <local:Artist>Powderfinger</local:Artist> </local:ArtistsControl>However, I kept running into obscure compile errors such as:
Cannot set content property 'Artists' on element 'ArtistsControl'. 'Artists' has incorrect access level or its assembly does not allow access.
Long story short, the problem was that my dependency property was of type IList<Artist>. In order for the collection to play nice with XAML, it needs to be a non-generic type (can’t even be a closed generic type). To resolve this I just created my own ArtistCollection type which inherits from ObservableCollection<Artist>. After that, the above XAML snippet worked fine.
#1, #4 and #6 all work fine “out-of-the-box”. That makes sense because they don’t rely on the logical tree in any way.
As I mentioned earlier, the first thing I tried at this point is to override the LogicalTree property in ArtistsControl:
protected override IEnumerator LogicalChildren { get { if (Artists == null) { yield break; } foreach (var artist in Artists) { yield return artist; } } }
This has the effect of fixing . . . nothing!
However, I did notice this error in the output window:
Cannot find governing FrameworkElement or FrameworkContentElement for target element.
This led me to change the base class of Artist from DependencyObject to FrameworkElement. This also did nothing to solve the other use cases. But it did change the error in the output window to:
Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=Tag; DataItem=null; target element is 'Artist' (Name=''); target property is 'ArtistName' (type 'String')
Hmmm. I have supposedly made the Artist objects part of the logical tree, so why can they not resolve anything further up the tree?
I had an epiphany around this point when I realized:
Just because the parent acknowledges the child, that doesn’t mean the child acknowledges the parent.
In other words, just because the Artist objects are part of the ArtistControl’s LogicalChildren collection, that doesn’t mean the Artist objects have their Parent property set to the ArtistControl. The logical tree is a two-way connection: the child is connected to the parent, and the parent is connected to the child.
So how do we connect the two? FrameworkElement.Parent is a get-only property, and WPF uses internal methods to alter its value. Fortunately FrameworkElement defines a couple of methods to help us here: AddLogicalChild() and RemoveLogicalChild(). All we need to do is call these methods to add and remove Artist objects to and from the logical tree.
Overriding the LogicalChildren property allows property inheritance to work. The attached sample will still work without it, but any inherited properties will fail to propagate within your custom logical tree unless you also override LogicalChildren.
When all is said and done, all use cases are satisfied and the following XAML works fine:
<local:ArtistsControl ...> <local:Artist>The Smashing Pumpkins</local:Artist> <local:Artist ArtistName="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> <local:Artist ArtistName="{Binding Tag}"/> <local:Artist ArtistName="{StaticResource StaticArtistResource}"/> <local:Artist ArtistName="{DynamicResource DynamicArtistResource}"/> </local:ArtistsControl>
I'm very pleased to announce that I have been awarded MVP for 2009 in Client Application Development. This is the first MVP award I have received. Being notified on the 1st of April was a little disconcerting, but against all odds it was not a hoax.
I look forward to continued involvement in the developer community over the coming years.
Here’s some great news for anyone doing WPF in LOB applications. Karl Shifflet and Jaime Rodriguez are travelling the World (well OK, parts of the World) to present a training course on WPF and MVVM in real-world applications.
This is an awesome opportunity and I wish I could be there. As luck would have it, I will be on leave in Australia precisely when they’re presenting in the UK :(
Oh, and did I mention it’s FREE!?
Get the full details here.
A colleague recently asked whether it was possible to invoke a WPF Command when the user presses a sequence of keys. As an example, consider the Format Document command in Visual Studio, which is generally mapped to Ctrl+K, D.
In WPF, a Command can be invoked via "input gestures" in a couple of different ways:
- When creating a
RoutedCommand, you can add any number ofInputGestures to theInputGesturescollection. Adding anInputGestureto this collection ensures that theCommandwill be executed (if it can be) when that gesture is performed by the user. - Via the
UIElement'sInputBindingscollection. Adding anInputBindingto this collection ensures that a certainInputGesturewill execute a certainCommandagainst thatUIElement.
WPF's built-in KeyGesture class is an InputGesture subclass that recognises a gesture based on keyboard input. The problem is, its definition of "gesture" is a single keypress. What I'd like to do is treat multiple keypresses as a single gesture, and KeyGesture does not support that.
Enter my MultiKeyGesture class. At first I thought I'd subclass InputGesture rather than KeyGesture, since the KeyGesture constructors reflect the single-key assumption. However, I found I had little choice but to subclass KeyGesture because the built-in WPF MenuItem control treats it as a special case in determining the text to display for the shortcut string. I could manually set the InputGestureText of the MenuItem, but I just couldn't be bothered for the purposes of this post.
Never mind though, because I can simply pass in Key.None to the KeyGesture constructor and override its matching logic:
public MultiKeyGesture(IEnumerable<Key> keys, ModifierKeys modifiers, string displayString) : base(Key.None, modifiers, displayString) { _keys = new List<Key>(keys); if (_keys.Count == 0) { throw new ArgumentException("At least one key must be specified.", "keys"); } } public override bool Matches(object targetElement, InputEventArgs inputEventArgs) { ... }
In other words, I'm only inheriting from KeyGesture so that our particular gesture implementation gels with other WPF classes that make annoying assumptions and break the Liskov substitution principle.
Notice from the constructor that the MultiKeyGesture class takes an enumeration of Keys. In order for a match to occur, the user must type in all of those keys (in order, of course). Generally, you would have a maximum of two keystrokes, but the sky really is the limit here. You could make the user type in "Ctrl+A, p, r, i, l, O, n, e, i, l, l, i, s, h, a, w, t" before your super-secret command is executed. You'd be pretty childish if you did that, but you could.
The Matches() method is where all the magic happens. It is this method that determines whether the user input matches the keys in the Keys collection. It does this with a mini state machine. As input is received, one of three things can occur:
- No match. The user entered the wrong key or paused too long between keystrokes. The index into the
Keyscollection is reset back to zero and the method returnsfalse. - Partial match. The user entered a matching key but not all keys have been entered yet. The index into the
Keyscollection is incremented and the method returns false (but marks theRoutedEventas handled). - Full match. The user entered the final matching key in the
Keyscollection. The index into theKeyscollection is reset back to zero and the method returnstrue.
That's it really. All the usual disclaimers apply about blog-quality code, but it does at least show that the scenario is possible in WPF.
If you look at the code, you'll notice a couple of other classes:
MultiKeyBindingMultiKeyGestureConverter
These aren't strictly necessary unless you want UIElement.InputBindings and XAML integration respectively. MultiKeyBinding is used to map a MultiKeyGesture to a particular Command for a UIElement (in XAML in this case, but could also be in code, of course):
<TextBox x:Name="_textBox"> <TextBox.InputBindings> <local:MultiKeyBinding Command="{x:Static local:Commands.Secret}"
Gesture="Ctrl+A,p,r,i,l,O,n,e,i,l,l,i,s,h,a,w,t"/> </TextBox.InputBindings> </TextBox>
MultiKeyGestureConverter is used to parse the Gesture attribute in the XAML into a MultiKeyGesture for the MultiKeyBinding.
Note that I didn't put much effort into these supporting classes at all. They are bare-bones to get the demo working.
Disabling an item in a Selector (such as a ComboBox) is easy once you understand that each item is automatically wrapped in its own container, and that you can apply a style to that container.
Suppose you have a view-model that represents a customer:
public class CustomerViewModel : ViewModel { private string _name; public string Name { get { return _name; } set { if (_name != value) { _name = value; OnPropertyChanged("Name"); OnPropertyChanged("IsEnabled"); } } } public bool IsEnabled { get { return !Name.StartsWith("Kent "); } } }
You can bind to the IsEnabled property from the item container's style thusly:
<ComboBox ItemsSource="{Binding Customers}" DisplayMemberPath="Name"> <ComboBox.ItemContainerStyle> <Style> <Setter Property="UIElement.IsEnabled" Value="{Binding IsEnabled}"/> </Style> </ComboBox.ItemContainerStyle> </ComboBox>
Then any Customer's who share my Christian name will be completely disabled:
The user is unable to select the disabled items with the keyboard or mouse, nor can they interact with them in anyway (eg. if there was a Button in the ItemTemplate of the ComboBox, the Button would also be disabled).
But what if I want to allow the user to interact with an item in the ComboBox, but not allow them to select it via the keyboard or mouse? There are numerous reasons you might want to do this, but my use case was as follows (this is a financial application):
- User can select from a number of market-related times (such as Open, Closing, Live, T - 1, T - 2 etcetera) in a
ComboBox User can alternatively click on a specific date in aCalendarthat is inside the sameComboBoxWhen the user selects a date in theCalendar, theSelectedValueof theComboBoxreflects this fact- The user cannot manually (via keyboard or mouse) select the interactive calendar item in the
ComboBox In addition to manually selecting values, the user can type values in theComboBox(ie. it is editable). For example, they might type "Open", "T - 1", or a specific date, such as "31/12/2004"- When typing in dates, the calendar should "scroll to" the correct month for the date entered
- Future dates are not permitted
First of all let me say that it might be possible to pull this off by re-templating the ComboBox such that its Popup displays all items and then a Calendar below the items. However, this has some serious disadvantages:
- re-templating a complex control such as
ComboBoxis time-consuming and error-prone - re-templating needs to be done for each theme supported by the application, and for each control we want to use this technique in (what if I want to change from a
ComboBoxto aListBox, for example) - I really want the interactive item in the
ComboBoxto be programmatically selectable. This will be particularly useful for those who want to use this technique with aComboBoxthat isn't editable
It's time to set the stage a bit. Please bear with me a little here. Here are the view models I threw together to get myself started solving this problem:
The view models take care of various details such as parsing and validating any text entered by the user. I could then put together some minimalistic data templates to render these view models:
<!-- explicit points in time are rendered as a Calendar so that the user can choose the point in time they want --> <DataTemplate DataType="{x:Type local:ExplicitPointInTimeViewModel}"> <wpf:Calendar SelectedDate="{Binding SelectedValue, Mode=TwoWay}"/> </DataTemplate> <!-- financial times are rendered as an editable combo box listing all times --> <DataTemplate DataType="{x:Type local:FinancialTimesViewModel}"> <ComboBox x:Name="_comboBox" ItemsSource="{Binding Items}" IsEditable="True" Text="{Binding Text, ValidatesOnDataErrors=True}"> <ComboBox.ItemContainerStyle> <Style TargetType="ComboBoxItem"> <!-- ensure relevant combo box items are disabled --> <Setter Property="IsEnabled" Value="{Binding Converter={StaticResource IsEnabledConverter}}"/> </Style> </ComboBox.ItemContainerStyle> </ComboBox> </DataTemplate>
Finally, I put a ContentControl in my Window and stuck a FinancialTimesViewModel in it:
var viewModel = new FinancialTimesViewModel(); viewModel.Items.Add("Live"); viewModel.Items.Add("Open"); viewModel.Items.Add("Closing"); viewModel.Items.Add("T - 2"); viewModel.Items.Add("T - 3"); viewModel.Items.Add(new ExplicitPointInTimeViewModel()); _contentControl.Content = viewModel;
Running this we can see that the templates are being used to render the view models:
As expected, the Calendar is completely disabled and useless so far as our use case goes. The first thing I tried to get around this was to just re-enable a child control inside the DataTemplate:
<DataTemplate DataType="{x:Type local:ExplicitPointInTimeViewModel}"> <ContentControl IsEnabled="True"> <wpf:Calendar SelectedDate="{Binding SelectedValue, Mode=TwoWay}"/> </ContentControl> </DataTemplate>
However, this had no effect. It was time to do some investigative work (otherwise known as Reflector) to determine how the ComboBox was making its decision to disable the item. I found this method in ComboBox that determines whether an item is selectable:
private bool IsSelectableHelper(object o) { DependencyObject obj2 = o as DependencyObject; return ((obj2 == null) || ((bool) obj2.GetValue(UIElement.IsEnabledProperty))); }
So if it's not a DependencyObject, the item is selectable. And if it is, the IsEnabled property is used to determine its "selectability".
But wait - we changed the IsEnabled property of the ContentControl within the template and it didn't enable its children. That's because IsEnabled doesn't get to make the final decision about whether a UIElement is enabled or not. From MSDN:
Note that this property is influenced by class-specific implementations of
IsEnabledCoreon particular elements, often at runtime. Therefore, the default value listed here is sometimes not effective.
Examining UIElement further, I found that the IsEnabled property was being coerced to false if any ancestor was disabled. That makes perfect sense really. You'd hardly want to have to manually disable all the children of a Panel when you disable the Panel itself. It’s much nicer that you can just disable the Panel and all children become disabled.
So what to do? I needed a control that didn't consider the IsEnabled state of any parent, and that's when I wrote the AlwaysEnabledControl:
public class AlwaysEnabledControl : Border { static AlwaysEnabledControl() { //override IsEnabled to coerce to true rather than considering the enabled state of the parent combo box item IsEnabledProperty.OverrideMetadata(typeof(AlwaysEnabledControl), new FrameworkPropertyMetadata(true, IsEnabled_Changed, CoerceIsEnabled)); } private static void IsEnabled_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { } private static object CoerceIsEnabled(DependencyObject dependencyObject, object value) { //we're always enabled return true; } }
As you can see, this control overrides the coercion logic in UIElement such that it is always enabled. Now, if I can wrap my Calendar in this baby:
<DataTemplate DataType="{x:Type local:ExplicitPointInTimeViewModel}"> <local:AlwaysEnabledControl> <wpf:Calendar SelectedDate="{Binding SelectedValue, Mode=TwoWay}"/> </local:AlwaysEnabledControl> </DataTemplate>
And here's what I get at runtime:
Hooray! Our Calendar is now enabled and the user can interact with it. However, there are some problems:
- As evident in the screenshot, the
Calendargets highlighted when the user mouses over it, which looks ugly - Not evident in the screenshot, the user can select the
ComboBoxItemcontaining theCalendarby using the keyboard or mouse
In reality I dealt with the second problem first because it was a deal-breaker. However, I'll talk about the first problem first here because it's conceptually easier.
I considered a couple of different solutions to the selection highlight problem. My first thought was to override the SystemColors.HighlightBrushKey and SystemColors.HighlightTextBrushKey resources for the ComboBoxItem containing the Calendar. The ComboBoxItem template uses these resources to look up Brushes when highlighting itself.
The problem was, I couldn't override these resources for individual ComboBoxItems - at least, not from within the XAML. I could override for all ComboBoxItems like this:
<ComboBox.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">Red</SolidColorBrush> </ComboBox.Resources> But attempting to override at the ComboBoxItem failed: <ComboBox.ItemContainerStyle> <Style TargetType="ComboBoxItem"> <Setter Property="Resources"> <Setter.Value> <ResourceDictionary> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">Red</SolidColorBrush> </ResourceDictionary> </Setter.Value> </Setter> </Style> </ComboBox>
This fails at runtime, and is not really what I want to do anyway. What I want is to selectively inject resources into the ComboBoxItem's Resources collection. I could not figure out how to do this from XAML, so I decided to ponder other solutions.
The solution ended up being reasonably simple. I added these Setters to the ComboBoxItem Style:
<!-- ensure we can't see the highlighting when we mouse over any always-enabled control --> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> <Setter Property="VerticalContentAlignment" Value="Stretch"/> <Setter Property="Margin" Value="0"/> <!-- most items require some padding, but the calendar control should not have any --> <Setter Property="Padding"> <Setter.Value> <Binding Path="." Converter="{StaticResource PaddingConverter}"> <Binding.FallbackValue> <Thickness>2,0,2,0</Thickness> </Binding.FallbackValue> </Binding> </Setter.Value> </Setter>
What we're doing here is making sure the content in the ComboBoxItem stretches across the entire expanse of the ComboBoxItem. Therefore, even if the interactive item is highlighted, we won't be able to see the highlighting. Of course, I need to also give the interactive item a non-transparent Background:
<local:AlwaysEnabledControl Background="LightGray"> <wpf:Calendar SelectedDate="{Binding SelectedValue, Mode=TwoWay}"/> </local:AlwaysEnabledControl>
Now running the application we see this:
It won't win any beauty contests, but we're edging closer and closer to the desired behaviour.
The last big problem that required solving is the fact that the user can still select the interactive item via the keyboard or mouse. This is counterintuitive and annoying for the user if they actually click just outside the Calendar.
It seems wrong that the ComboBoxItem is considered selectable given that it has been disabled (remember, it's just the contents inside the ComboBoxItem that are enabled). The key to solving this problem is understanding that the ComboBox executes different selection logic based on whether the drop-down is open or not. Indeed, if I run the application at this point and try to select the interactive item without opening the ComboBox drop-down, I can't. But if I open the drop-down first, I can cursor down until the Calendar is selected.
When the drop-down is open, the ComboBox actually delegates to an internal method on ItemsControl to select the next item. That method (ItemsControl.NavigateByLine) uses keyboard navigation to determine an items eligibility for selection - not the IsEnabled state of its container. So, because the Calendar and its children can accept focus, the ItemsControl considers it eligible for selection.
Thankfully, we can dig ourselves out of this hole by disabling directional navigation on the ComboBoxItems:
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="None"/>
This has the effect of making the contents of the ComboBoxItem “invisible” to the logic used by the ItemsControl. Therefore, we can no longer select the Calendar with the keyboard.
But the mouse can still be used to select it. At first glance, it looked like I could workaround this by setting IsHitTestVisible to false on the ComboBoxItem and then overriding the coercion logic like I did with the IsEnabled property. However, that didn't seem to work and I'm not entirely sure why. I suspect there are assumptions about hit test visibility in parent/child relationships ingrained into other areas of WPF.
Again, solving this required some inside knowledge into how the mouse clicks were being handled by the ComboBoxItems. Basically, ComboBoxItems pass the various mouse events to the owning ComboBox and the ComboBox decides what to do with them. It's the MouseLeftButtonUp event that causes the item to be selected. Therefore, I added this to the AlwaysEnabledControl:
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnPreviewMouseLeftButtonUp(e); //if the user clicks directly on this control, don't let that click propagate to the container if (VisualTreeHelper.HitTest(this, e.GetPosition(this)).VisualHit == this) { e.Handled = true; } }
As you can see, this override ensures any clicks directly on the AlwaysEnabledControl are swallowed. That means the ComboBoxItem will never see the event and therefore the item will not be selected.
There are some other points of interest in the code base, but I'll let you discover them yourself. The end result is that we satisfy all our requirements. And with some minor modifications to the XAML, you can swap the ComboBox out for a different Selector (such as a ListBox).
This technique of having interactive items that are "disabled" from the perspective of the Selector in which they're contained could be useful in quite a few different scenarios. Here are a couple off the top of my head:
- A colour pick list that contains the names of many common colours and then an interactive colour wheel at the bottom
- A multi-select list of customers (or whatever) with an interactive search item up the top. When the search item is used, it actually resolves to a dynamic query that selects any number of customers based on some criteria
You should note that the attached solution was my POC only. I ended up refactoring the code a fair bit to make it cleaner and more extensible.
Enjoy!
This morning I listened to Glenn Block's MEF talk on Hanselminutes, wherein he touched on the differences between MAF and MEF. I was glad he did. Not only are their names confusingly similar, but their goals seem so on the surface, too.
Glenn sums up the differences well by saying that MEF is about extensibility whilst MAF is about isolation. Moreover, they are not mutually exclusive. It is entirely possible - and legitimate - to use both together.
Indeed, this is something I've been meaning to try and I will cover it in this post. Specifically, I will show how a MAF add-in can use MEF to compose a set of unknown parts to do its job.
First of all, I started with my skeletal MAF solution. I'm really glad I took the time to put that thing together - it has saved me a lot of time with these MAF-related blog posts ;)
Next up, I grabbed the latest preview of MEF from the MEF CodePlex site. I copied the System.ComponentModel.Composition assembly into my skeletal solution and referenced it from my sample add-in. MEF will eventually be part of the framework (version 4.0 is the target) but for now it is standalone.
Then, I defined the interface my add-in will rely on (import):
public interface IMessageProvider { string Message { get; } }
It will import any implementations of this interface it finds and print out the corresponding messages. I added one implementation of this interface to the add-in project:
[Export(typeof(IMessageProvider))] public class SampleMessageProvider : IMessageProvider { public string Message { get { return "A message provider in the same assembly as the add-in."; } } }
I added a Compose() method to the add-in:
private void Compose() { var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var container = new CompositionContainer(new DirectoryCatalog(directory)); var batch = new CompositionBatch(); batch.AddPart(this); container.Compose(batch); }
This method is called by the add-in when it is initialized. It composes the MEF container by looking for all parts in the directory containing the add-in. The easiest way to get that directory was to use the location of the currently executing assembly, since that assembly is the add-in itself.
The add-in imports all message providers:
[Import] public IEnumerable<IMessageProvider> MessageProviders { get; set; }
And then it iterates over them during its Initialize() method:
public void Initialize(IHost host) { Compose(); Console.WriteLine("This is the sample add-in, running inside host with name '{0}', version {1}. AppDomain name is '{2}'.", host.Name, host.Version, AppDomain.CurrentDomain.FriendlyName); foreach (var messageProvider in MessageProviders) { Console.WriteLine(messageProvider.Message); } }
Running the application at this point works just fine and we see the single message provider was found:
Now I wanted to add another message provider in a completely different assembly to the add-in. So I added a new project called MessageProviders. This project references both the System.ComponentModel.Composition assembly as well as the add-in assembly (so it can use the IMessageProvider type). Importantly, the add-in assembly does not reference the MessageProviders assembly. The MEF catalog ties the two together for us. Also, you could imagine that the IMessageProvider interface could be in a standalone assembly, so that the add-in assembly and MessageProviders assembly don't need to reference each other.
I added another message provider to the new project:
[Export(typeof(IMessageProvider))] public class ExternalMessageProvider : IMessageProvider { public string Message { get { return "A message provider in an external assembly."; } } }
Then I ensured the build script copied the output of this new project to the add-in's directory. I hit F5 and things just worked:
Both message providers were found by MEF running in the context of a MAF add-in.
To me, one of the benefits of achieving isolation with MAF is that add-in authors are free to use whatever technology they want to meet the needs of their add-in. If they need dependency injection, the host has not imposed on their choice. They can use Unity, StructureMap, autofac, ObjectBuilder or whatever best suits them. And if they need composition, they can use MEF.
Not too long ago I was sitting at my painfully uncomfortable work desk minding my own business when I sensed a presence over my left shoulder. Turning, I discovered one of my managers staring intently at my screen.
"I hope you're going to rename that", he said, pointing at my monitor. He was referring to a method I had named "Synchronize". "We spell that with an 's' here", he stated, perhaps forgetting that Australians share British spelling - or perhaps forgetting that I was Australian.
Assuming that he was joking, I smiled and chuckled. "I'm serious", he said.
And he was.
And I was flummoxed.
Looking through my team's code base I found that they are indeed using the Queen's English in naming their methods and types. I completely disagree with this decision. This post serves as a reference for my reasoning, and as something I can point future colleagues to.
The reason is really simple, actually: consistency. For better or worse, all Windows and .NET APIs are in American English. The last thing I want to see in a code base is this:
public class MyClass { private SomeComponent _component; public void Initialise() { _component.Initialize(); } }
Since SomeComponent was developed by those who conform with the status quo, the code has inconsistent spelling. It's inevitable, confusing and sloppy.
We have coding conventions to reduce inconsistencies in code bases. In the interests of said consistency, one of your coding convention should be to use American English. Indeed, I suspect the framework design guidelines state this, but I do not have a copy of the book to confirm.
In saying all this, I can't help but picture my Mum and my high school English teacher - Mr. Butler - standing sternly in front of me, scolding me for my unpatriotic attitude.
Mum, you will always be my "Mum" and never my "Mom", unless you run my software in the US. And if you ever read my code I warn you now that you will see names such as "Initialize", "Synchronize", and "Color". You can scold me only if those spellings surface in the user interface.
Mr. Butler, you practically accused me of cheating in front of my entire year 11 class, so I make no apologies†.
Anyway, my point is that coding in anything other than American English will make your code base inconsistent and harder to maintain. We switch contexts when communicating all the time (think SMS and IM where a whole different lexicon applies), so we should be able to switch context when communicating in code. No biggie, but it makes a big difference to the resultant code.
† Just in case someone takes this too seriously, I will point out that Mr. B was one of the best teachers I ever had. This was a very rare black mark against his name. I had received 98% for my essay on Animal Farm. After congratulating me, he mentioned how similar it was to my sister's effort of two years past, and asked me pointedly whether I had copied it. I hadn't. Indeed, I didn't even know my sister had written an essay on the same topic. I think it far more likely that my sis is a cyborg and she traveled back in time to copy my essay. I will have to ask her about that.
I’m on leave at the moment and was looking for something a little different to occupy me. To that end, I spent some time over the past couple of days adding resource compression to Kentis. This took the download size from 12.3MiB down to 1.9MiB, so it was certainly worth it!
Kentis used to be hosted on GameDev.net, but in attempting to update my project I found out my membership had expired (no surprise really, given how long it’s been). I was willing to part with a few quid until I saw that their preferred payment method is PayPal, which I hate with the heat of a thousand suns. Therefore, I’ll be hosting it myself, and I’ll provide the details in my next blog post.
For now, however, I just want to discuss the improvements I made.
Image Compression
Previously in Kentis I was using solely bitmaps as my graphic resources. As far as storage efficiency goes, that’s pretty much the worst possible choice. The reason I was using them was for simplicity – I didn’t have to do any conversion in order to consume them in my game because DirectX understands bitmaps directly (I’m using DirectX 7, which does not support JPEGs or PNGs natively).
I have two basic image types in my game: backgrounds and sprites. The backgrounds are large, complex in color, don’t require transparency, and can be stored in a lossy format. The sprites are smaller, have far fewer colors and gradients, do require transparency, and must be stored in a lossless format. JPEG compression is perfectly suited to storing the backgrounds, and PNG is the best candidate for the sprites.
My first foray into providing a solution was to use the ijp libraries. However, I couldn’t even get the simplest of console applications to decode a JPEG without the jpeg_read_header() function throwing an access violation. I never did figure out why, so perhaps I’ll post on stackoverflow later to see if anyone can shed some light.
Anyway, ijp would only be a partial solution because it only supports JPEGs – not PNGs. So I turned my attention to a windows API called StretchDIBits(). This API should allow you to copy a bitmap, JPEG or PNG to a device context (DC). Long story short, I couldn’t get it to work and I’ll come back to my theory why in a minute.
At this point I was getting a little tired of not getting anywhere. I was about to give up and go and watch Band of Brothers on Blu-ray when I happened upon the CxImage library on CodeProject. It looked like a good alternative to the StretchDIBits() API, so I thought I’d give it a whirl. I had to fix some things first though. For one, the projects were not set up with the correct runtime library settings. Secondly, when I tried disabling functionality I didn’t need (such as extra graphic formats, layers, and encoding support) it no longer compiled.
After I got it to compile and link with Kentis, I again ran into problems. I don’t remember the manifestation of the problem, but the point is I spent a good 4 or 5 hours scrutinizing and debugging my code. I eventually tracked down the problem to my .rc file (resource script). Visual Studio had gotten confused somehow when I was making changes to my resources and this file was far from correct. I updated it by hand and recompiled and relinked. Success!
I suspect the problem with the .rc file also prevented the StretchDIBits() API from working. I think I’ll test this theory a little later, because it would be good to reduce the binary size even further. CxImage is a fantastic library, but it has way more functionality than I need. I spent a good amount of time getting it down to a minimum, but getting rid of the dependency altogether may yield even better results.
Anyway, I managed to shave off roughly 4MiB from the executable size by compressing the graphics.
Audio Compression
All the audio in Kentis was stored in WAVE format. Again, this was to avoid any decoding steps but came at the cost of significant storage space. Unlike graphics, all the audio could be encoded in a lossy format.
I settled on Ogg Vorbis as the format. I converted each of my .wav files to .ogg files, incorporated the ogg and vorbis libraries into my code base, and updated parts of game’s audio layer to do the decoding.
It all went rather well. The only hiccup was that the decoding time for the music tracks was excessive (around 2-3 seconds). I tracked down the problem to resizing of a vector<char> I was storing the decoded data in. Even a single resize was costing a lot of time. Therefore, I put in a call to vector::reserve() and an assertion that would let me know if resizing ever occurs in the vector.
Compressing the audio took off a further 6MiB or so off the executable size.
What next?
My goals for these changes were simple: reduce the executable size without affecting functionality at all. I did remove one of the five backgrounds (because the contrast was poor) and two short sounds (because the vorbis libraries didn’t like the sampling rate) but other than that, it is functionally identical to the previous 12.3MiB executable.
I am toying with the idea of doing other updates or doing a different game entirely, but haven’t decided on anything yet.
At work I have the somewhat esoteric requirement of referencing multiple versions of the same assembly from a consuming assembly. The reason why I need to do this is superfluous to this post and I won’t be elaborating on that. It’s the how that is the topic of this post. Regardless of why you need to reference the same assembly multiple times, this post should help you do so if you run into issues.
The first thing you might try is simply adding a reference via Visual Studio’s Add Reference… dialog. However, you’ll get an error if you do this:
A reference to 'C:\Sample\Lib\Example.Model.dll' could not be added. A reference to the component 'Example.Model' already exists in the project.
As highlighted in the error message, Visual Studio uses only the assembly (or project) name to identify references. Therefore, the version of the assembly does not help to disambiguate the reference.
The C# compiler (csc.exe) has a /reference switch to supply references that takes the following format (from MSDN):
/reference:[alias=]filename
Notice that an alias can be optionally supplied. Further down in the MSDN documentation you will read:
Sometimes it is necessary to reference two different versions of the same component from within one assembly. To do this, use the alias suboption on the /reference switch for each file to distinguish between the two files. This alias will be used as a qualifier for the component name, and will resolve to the component in one of the files.
To be clear, the C# compiler does allow us to reference different versions of the same assembly. Those references just need different aliases to disambiguate them.
Cracking open the Visual Studio project file for our consuming assembly, we find something like this:
<Reference Include="Example.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8c3ef16ce2e2f88d, processorArchitecture=MSIL"> <HintPath>..\Lib\2\Example.Model.dll</HintPath> <Private>False</Private> </Reference>
Thankfully, the Visual Studio limitation can be overcome simply by editing the project file directly. So we can add a reference to version 2 of our assembly with a simple copy, paste and edit:
<Reference Include="Example.Model, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8c3ef16ce2e2f88d, processorArchitecture=MSIL"> <HintPath>..\Lib\1\Example.Model.dll</HintPath> <Private>False</Private> <Aliases>legacy2</Aliases>
</Reference>
<Reference Include="Example.Model, Version=3.0.0.0, Culture=neutral, PublicKeyToken=8c3ef16ce2e2f88d, processorArchitecture=MSIL"> <HintPath>..\Lib\1\Example.Model.dll</HintPath> <Private>False</Private> <Aliases>legacy3</Aliases>
</Reference>
Notice how we’ve added the alias to differentiate the two references in the code. When we load such a project file in Visual Studio, it gives us a warning indicator next to any references it considers to be duplicates:
However, rather than complaining about these at build time, it simply passes the details of these references onto the C# compiler and lets it sort things out:
csc.exe
/reference:legacy2=..\Lib\2\Example.Model.dll
/reference:legacy3=..\Lib\3\Example.Model.dll…
As such, we can consume the referenced assemblies as follows:
extern alias legacy1; extern alias legacy2; extern alias legacy3; namespace ConsumingLibrary { public static class Consumer { public static void CreateInstances() { //version 2 of SomeClass var v2 = new legacy2::Model.SomeClass(); v2.SomeProperty = "test"; //version 3 of SomeClass var v3 = new legacy3::Model.SomeClass(); v3.SomeProperty = "test"; v3.SomeOtherProperty = "test"; } } }
The extern alias keyword allows us to pull in the types defined by the assemblies that have been assigned aliases outside of the default “global” alias. Thereafter, we can qualify types with those aliases as per the above example, or even use those aliases to qualify using directives:
using legacy2::Model;
One thing to look out for with all this, is that WPF projects don’t seem to like it. If you add these multiple references to a WPF project the compiler seems to pick one of the references at random and ignores the rest.
Further to this, the only way I could get consistent behavior from the AppDomain.AssemblyResolve event was to separate the consumer into its own library. The entry point to the application attaches a handler to the aforementioned event and then calls into the consuming library to construct the types. Attempting to combine these two activities into the same assembly (even in separate types) would result in the event not always being fired.
Finally, Visual Studio sometimes has trouble providing Intellisense in these scenarios. And sometimes it erroneously places squiggly compile errors where it shouldn’t. Sometimes you just have to ignore them and build.
To see this all in action, you can download the little sample I put together here.







