My friend Karl, created an article on locking. It is really nice because he made some dead simple examples that are not only interesting but funny to read…
You must read his article….
Have loads of fun reading it
So, let me start by saying this, I am not a blend guru. I never use blend, I prefer Visual Studio. I was showing off Blend 2.5 March 2008 Preview to the designers at work and I noticed that the Silverlight DataGrid was not showing up in the list of controls in blend. Then I remembered that the Datagrid control for Silverlight 2 Beta 1 is in the System.Windows.Controls.Data dll which is not added as a reference by default in Silverlight projects.
So how can one make the Datagrid control show up in blend for a Silverlight project?
The answer is very easy. You have to add a reference to the System.Windows.Controls.Data dll. To do this right click on the References folder in blend and select Add Reference (as shown in the image below)
An open file dialog should pop up. The System.Windows.Controls.Data dll is located in the folder C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client\. Enter that path in the address bar and a list of Dll should popup. Select the System.Windows.Controls.Data dll and you’re done
Now that you added the reference to the System.Windows.Controls.Data dll, the Datagrid control should appear in blend.
If you are going to use the DataGrid control for Silverlight I would suggest that you read this very useful blog post
Have loads of fun with Silverlight…
In my previous article I explained how one can use the Mediator Pattern together with the MVC Pattern to structure the code in a very neat way. If you did not read my previous article I would suggest that you do, since I am basing this post on the assumption that readers already read that post.
I am writing this post because some friends from WPF Disciple suggested that I use a better example for the MVC+M. I agree 100% with them since the example that I did in my previous post was not the best one I could pick up…
Today I’ve got a new problem that I want to solve using the MVC+M. As the title of the post suggest, we are going to build a File Explorer and hopefully it will look something like this.
Yea, that’s where AvalonControlsLibrary and all other projects of mine live
This application is very simple to explain because I would assume that everyone reading this post has used a File Explorer. Basically we have a TreeView that shows the directories and when a directory is selected the list of files in that directory show up on screen.
The problem is that we do not have a fixed list of objects. The list is generated on the fly. If we had to load all directories in memory we would have a big performance hit + I don’t want to imagine the memory consumption. So for the TreeView I used the Flyweight Design Pattern. I will not go into details of this pattern since it is not the purpose of this post, but to summarize, each node loads a dummy child so that the user can expand the items. Once an item is expanded the TreeView controller loads the child directories of the directory being expanded.
You’ll say “OK… But what does this have to do with the Mediator?”. The Mediator comes in handy for our second problem. When an item is Selected the list of files show up in the file list (on the right hand side of our application).
So the problem here is, we have a Dynamic Hierarchal List + we have a Treeview (which does not have an IsSynchronizedWithCurrentItem property that can make the underlying ICollectionView notify us with the currently selected item). Speaking of which we now don’t even have one ICollectionView, instead we have one for each level.
How can we tell the File List Controller that an item is selected without coupling it with the Tree View Controller?
In such a case the Mediator is key, because the mediator will make the communication between the 2 controller very easy and loosely coupled. Let me first introduce the entities we have here
- DirectorySelectorController (mentioned above as TreeView contoller)
- FileSelectorController (mentioned above as File List Controller)
OK so lets’ do this… And guess what we are going to do this in 3 steps once again.
Step 1 – Publish the Directory Selected message via the Mediator
Step 2 – Register the FileSelectorController to receive a notification for the Directory Selected message.
Step 3 – Handle the Directory Selected message in the FileSelectorController and get the files to display.
Lets now talk in C#. The following is the code to do the above mentioned 3 steps.
That’s all folks …. Download the full source code to see all the rest…
Developers are like artists. Everyone has his own style. For example, right now the Mediator implementation that I did, is using an interface driven design where you have an interface IColleague and the mediator notifies the colleagues passing the message that is being sent. One can implement a Mediator that uses strongly typed delegate so that you can avoid doing the switch statement (in the MessageNotification method) and implementing the IColleague interface for each controller. So the implementation of such a Mediator would look like this
The Colleague that want to register simple do the following
This would totally eliminate the switch statement and the ICollegue interface…
One thing that I have been discussing with some friend from WPF Disciples is, What about big systems? Would big systems have to define loads of Messages?
The answer (at least how I see it from previous experiences working with this pattern) is NO. Why? Because the messages would be only for the controllers part. The other parts of the system would not need such a thing because if the controllers can talk together, the other entities would not need to. If we take the example of the File Explorer, the Views do not need to communicate because the controllers are synchronizing with each other. The views are just reading the data from the controllers. The model does not need this system either because the model will just give data that is being requested from the controller. So, please do not misinterpret this and use this system all around because you would create a MONSTER!
Josh Smith, also pointed out a very good point. What about memory leaks? If controllers do not unregister from the mediator once that the contoller is disposed than the controller would still exist in memory. This is a fact! I did not implement an unregister in the mediator because till now I only had controllers that do not get disposed throughout the application life cycle. Yet to implement an unregister would be just a piece of cake. All you have to do is to ask the mediator to remove the reference to a specific controller when the contoller is being disposed.
Besides the Mediator, there are loads of other ways of doing this, yet I decided to stick to this one because currently I feel that this pattern is given me the flexibility I need.
I like how this works because I feel that I can have a loosely coupled and high cohesion code base.
Loosely coupled, because the controllers know nothing about each other and I can just disable or reuse one of them at any point in time.
High cohesion, because knowing that I can make controllers communicate in an easy way, I create controllers that have one responsibility.
First of all I am assuming that the readers already know how to use the MVC design pattern for WPF (or at least read about it and understand the concept). If not I would suggest that you read this brilliant post by Josh Smith. I am writing this article because recently I found a problem when using the MVC in WPF and I think I found a neat solution. Well I said that “I” found the solution, that is not true. The pattern that I am going to talk about is called the Mediator Pattern and I found it in the Gang of Four book that I was reading recently. I decided to mix the 2 patterns together and the result was beautiful code.
Warning: This article is a bit long. Readers can fall fast asleep
The way I see it, Views must be as small as possible and handle only one specific job. Let’s do a practical example. Let’s say we have an application that displays a list of products. The application also lets you click on a specific product and the details of that product would show on the side. A search feature is also provided in this application. So our application would look something like this (I coloured the different sections of the app to make them more obvious)
Let me introduce the Entities that we have here
Controllers (These are simple class nothing more)
Views (These are all User Controls)
All views create an instance of the related Controller and set the Controller instance as the DataContext. By doing this the View can data bind to the properties of the Controller and also the Controller can handle routed command and routed events from the View since the Controller is now in the WPF logical tree. In this way the View has 0 lines(excluding the InitializeComponents) of code in the code behind file and all logic is inside the Controller class. By doing this you can easily Unit Test the logic and also Designers can use tools such as Expression Blend without having any problem because the logic is handled in the controller class and not in the view itself. Just like MVC in Web so to speak. Imagine commands in WPF as being the Routed URL for the controller to handle.
One may say “Wow, that’s a lot of classes” but hey if you want to be flexible, scalable and have code reusability that is the way to go. If not, then go ahead and put everything in one class but the result will be strongly coupled entities that are not reusable. Sometimes this is perfectly acceptable and so YES go ahead and do that. But let’s say you need to do a Search feature in another page. With MVC you can just re-use the search view and search controller in the other page.
In the MVC for WPF (or better in one of the implementations), there is a strong use of Routed Commands (sometimes one may use also Routed Events, well at the end of the day a RoutedCommand is just a Routed Event + the Command Pattern nothing more). The problem with Routing Commands is that the communication is always done from child to parent in the logical tree. In the application above there is a need of something different. Basically the Controllers need a way how to communicate. Yet we do not want that the Controllers know about each other because if that was so why not create 1 View and 1 Controller. We must ensure that no coupling is made between the controllers.
In the sample application above the ProductListController is handling the SelectionChanged event of the ProductListView. ProductListController needs to communicate this to the ProductDetailsController so that it updates the data that is currently being shown in the ProductDetailsView.
The question is how can you achieve this?
The Mediator pattern can be described as a ChatRoom. In a Chat room there are Colleagues (the persons in the Chat Room) and via the Mediator (the chat room itself) they exchange messages. The same can be applied for our Controllers. There would be 1 Mediator and all Controllers communicate to each other via the Mediator. In simple english the Colleagues would be the Controllers.
The following is the Class Diagram for the application I mentioned above
The interface for the Mediator would look something like this
The signature of the methods would look like this
The IColleague interface is an interface that all Controllers implement and looks like this
The Signature for the MessageNotification would look like this
With the Mediator pattern Controllers can send messages to each other without knowing of each other. Let’s do an example to try and make this more clear. Lets use the problem that I described above.
“ProductListController is handling the SelectionChanged event of the ProductListView. ProductListController needs to communicate this to the ProductDetailsController so that it updates the Data that is currently being shown in the ProductDetailsView”
All we need to do is 3 things
- 1.0 ProductDetailsController registers to the SelectProduct message (the message is just a constant string defined in a common class named Messages)
- 1.1 ProductDetailsController updated the Selected Product when this message is sent.
- 2.0 ProductListController sends a message via the Mediator that a new product has been selected
Code for 1.0
Code for 1.1
This will set the CurrentProduct property of the ProductDetailsController to be the new product that has been selected (the product object has been sent via the Code in 2.0). The CurrentProduct property of the ProductDetailsController is being data bound in the view. When the CurrentProduct is set the property raises a PropertyChanged notification, so that the binding is updated with the new value.
Code for 2.0
hehe… Funny name but for me this is doing miracles. I am currently using this in one of my projects at work and I can confirm that this absolutely works. One may say but this application could have been done with other thing that WPF offers, and I agree 100%. The example application that I used in this post can be easily implemented by putting the list of data in the Model and binding to it (like in MVVM). For the selection part, you can use the Current item of the ICollectionView and everything would work. Yet when you need to do more than just “Select item and data changes somewhere else” than the MVC + M comes useful.
MVC + M is a neat mix of the MVC pattern with the Mediator pattern. The MVC makes things much easier to test and much more isolated and controlled. The Mediator makes communication between Controllers possible in a loosely coupled manner. For me this works really well and I hope that it will do the same for your applications. Download the source code to have a look at my humble implementation.
Any comments, questions and suggestions are as usual most welcome…
P.S I am sorry if this post was a bit long but I didn’t manage to make it any shorter.
I woke up early this morning and decided to play around with Silverlight…. I love Silverlight it makes me feel like I am developing in WPF yet Cross Browser and Cross Platform…. can it get better than that???
Yet, this morning I had to swear a bit !
I was building a Silverlight custom control (as usual that the first thing I try out in a new platform ) and I found a post that helped me a lot. The first problem that I found was Visual Studio does not have a template for a ResourceDictionary for Silverlight.
As you all know in order to build a custom control Generic.Xaml is one of the most important things to do. Generic.Xaml would contain the UI of the custom controls.
Yet thanks to the post I just mentioned I got through this by create a Text File (naming it generic.xaml) and setting the Build Action to Resource. You must also clear all other fields… something like this
I said ok, I have the generic.xaml all set up now all I need to do is to create a Style for the control that will act as the UI for my new Custom control. First thing I did was to create an xmlns declaration so that I can style my control. something like this
As you can see I did not add the assembly part in this because I said since the generic.xaml is in the same project of the control class I would not need it. At least that is what you would do if you are a WPF developer. But guess what I ran the application and BAMMMM!!! I got a AG_E_UNKNOWN_ERROR. This is a nice error to get in 7 o clock in the morning
I started looking around to try and translate this error and I found a very helpful post. Yet still, I could not find the source of the problem… Then I tried something out, just to say that I tried it… basically I added the assembly part in my generic.xaml xmlns declaration… something like this
And Guess what… It worked!!!
For me this is quite crazy because I never had to do such a thing in WPF. Actually if you try to do that in WPF you would start getting an error because the generic.xaml is in the same assembly of the control you are trying to reference. But anyway, Silverlight is still BETA and I am more than sure that this will be fixed in the near future.
Ok so with the xmlns problem fixed, I was hoping to find no other surprise but after a minute I got another one!!!
Usually when one is building a controls library you would create a ResourceDictionary for each control so that the generic.xaml would not get cluttered. And then you merge all dictionaries in the generic.xaml by using the ResourceDictionary.MergedDictionaries something like this…
But guess what. There is no such thing YET in silverlight
so you have to put all the resources for the controls in the generic.xaml. I didn’t find a workaround for this yet but I will update this post if/when I do.
Silverlight is really cool. Don’t let small things like this get in the way. I am more than sure that issues like this will be fixed in the near future…. I remember when WPF was still in Beta there where similar things. The only difference with Silverlight is that there is already WPF and people expect that Silverlight has the same capabilities. Eventually this will happen but for now we must wait
Last 2 words – Silverlight Rocks!
Unfortunately the WPF native treeview or treeview items do not expose a property to determine which item is the root node in the treeview. I needed such a feature and thought to put it on my blog…
What is a treeview?
Well believe it or not a TreeView is just an Items Control nothing more. Yes, an ItemsControl that creates TreeViewItems as it’s Item Containers. The TreeViewItems are also ItemsControl so a recursive data structure is formed and the TreeViewItems generate there own child nodes.
Today I will not go into details of how the treeview and ItemsControl work… For more info on this visit Dr.Wpf Blog. I will discuss more how I implemented the root nodes for the treeview.
So an ItemsControl has a very special method that one can override to do some custom logic, “PrepareContainerForItemOverride“. The following is the signature of the method
Basically this method gets called whenever an item (in our case a TreeViewItem) is being created and decorated with a DataTemplate (if set). In this method we can set a property of the TreeViewItem to identify the item as a root node.Ok, lets start. First we need to sub class the Treeview control. Once we did that we need a way how to attach information to the TreeViewItems… HMMM.. what better could do this then Attached Properties. Once we have all this, we need to set the attached property to True for the root nodes and we are done …. something like this
So the most important part is where we set the Attached property IsRootNode to true (Please also note that by default the Attached property is set to false). You would be wondering, But wouldn’t this make all TreeViewItems root nodes???!!??? And the answer is, NO. Because the Treeview only generate root nodes. all other nodes are generated by the TreeViewItems themselves (Remember that the TreeViewItems are ItemsControl as well :)).
Once we have the property IsRootNode set we can restyle the TreeView as we want by using a Control Template. something like this
The most important part of this ControlTemplate is the Trigger on the attached property local:MyTreeView.IsRootNode.Here we are making the RootNodes for the treeview look different from all other nodes…
Hope this post helps…. Please contact me if you need any help
If you look at Vista User experience guide, one thing that is a must have is the Input Prompt. I think that this is very important to improve the user experience. Yet unfortunately this is not supported natively by WPF
But don’t worry because AvalonControlsLibrary is at the rescue
I had noting to do today so I decided to create this functionality and share it with you guys… You would say, aha; here comes Marlon with a new control. But NO. This is not a control as such. What I have created is a class with some attached properties that can be used to have the Prompt Input feature for any control (or better any control that would make sense such a feature). I choose the attached properties approach rather than creating a custom control for the simple reason to support any control that you wish to have an input prompt like the one displayed in the image below.
As you can see in the image above I am using the Input Prompt both for the TextBox and the ComboBox. And yes you can use it with any control that you want…
Well using this feature is quite easy, all you have to do is to set an attached property in your control. Something like this…
[where local is the XAML namespace mapping]
In total there are 8 properties that you can set which are
Please note: You must set the InputPrompt.PromptText in order for this to work all the other properties are optional. Also you must have you control under an AdornerDecorator because the InputPrompt will draw the prompt text in an adorner.
If you use the Input Prompt with a textbox the input prompt will be much more intelligent. What do I mean by this? Basically the Input Prompt handles the Text Changed event of the TextBox and if the user enters no text the prompt re appears. The same happens if the TextBox looses focus and there is no text in it. I did this behaviour for the TextBox because this is the standard behaviour for an Input Prompt for textboxes.
Well it’s quite simple. Basically an Adorner is placed on top of the control which sets the Attached properties and draws the InputPrompt.PromptText. Besides drawing the text this also draws a rectangle covering the surface of the control so that as soon as the user click the control(or better mouse down on the control), the adorner disappears and the control gets activated once again.
When the InputPrompt.PromptText is set for a TextBox, the input prompt will register to the LostFocus event and the TextChanged event and make sure to display the Prompt Text if the Text of the TextBox is to empty.
All this will be included in AvalonControlsLibrary v3 but I decided to upload a demo as a stand alone so that you can start using this immediately.
Hope you like this and as usual I am all ears for feedback and suggestions….
I am collecting suggestions for AvalonControlsLibrary v3. AvalonControlsLibrary v2 was a great success, thanks to all you that helped me come up with ideas on what to include in the library.
I already have some ideas on what to include, but I believe that your input is imperative… I need your help !!
Please post ideas/suggestions as comments to this post or here at CodePlex. If you prefer send me an email at marlongrech AT Gmail (sorry for not putting in the full email but I am receiving loads of spam )…
Thanks a lot for all your support