Three days ago (being more specific, on Friday 13th ;) ) I've passed my first Microsoft developer's exam, 70-536 TS: Microsoft .NET Framework - Application Development Foundation, scoring 876 points out of 1000. In short, I had 40 question and 135 minutes. As far as questions are concerned, there were many about serialization (rather not very straightforward), interoperability and globalization. No questions about mailing functionality. The questions ranged from very simple to quite though. Most of them were single choice questions, I got maybe three or four multiple choice ones.
Some say this is an easy exam. Well, I wouldn't say so, because the exam covers almost every .NET basic subject. In order to pass, you need to have solid theoretical background, but at the same time you need to get you hands dirty by playing with some code samples too. I recommend examining the official Training Kit (now there's 2nd edition, the first one was quite buggy so don't rely only on that book). Skimming MSDN seems like a good idea too ;) However, there's no better source of knowledge than the developer's head and experience. Most of the questions I answered because of my experience and not because of the books!
Next, I'm going for the exam 70-502: Microsoft® .NET Framework 3.5—Windows® Presentation Foundation. Good luck with your own certifications!
Sunday, March 15, 2009
Tuesday, February 24, 2009
Lack of AttachNewRegion method in Prism 2.0
Today I have switched to Composite WPF and Silverlight 2.0 (known as Prism 2.0) in one of my current projects. The transition was quite smooth (I used a guide which I found here), although I found one issue - the IRegionManager interface does not contain the AttachNewRegion method :( This made me very unhappy because I used this method in the implementation of a IMenuService which is responsible for managing the main menu control within my application by exposing a friendly interface to all modules. After small source code investigation I realized that indeed there's no sign of the mentioned method. After reading interesting post here, I decided to write one myself, which was a trivial task ;) Here's the code:
As you can see, this is a very simple extension method that extends the IRegionManger interface. Inside, I simply set the region manager and the region name on the desired UI element.
This solution is very simple, still it works fine (at least for me). If you have any troubles with it, let me know.
using System;
using System.Windows;
using Microsoft.Practices.Composite.Presentation.Regions;
using Microsoft.Practices.Composite.Regions;
namespace Mammoth.Presentation.Infrastructure.Common
{
public static class RegionManagerExtensions
{
public static void AttachNewRegion(this IRegionManager regionManager, object regionTarget, string regionName)
{
if (regionManager.Regions.ContainsRegionWithName(regionName))
throw new ArgumentException("Region already exists.", regionName);
RegionManager.SetRegionManager((DependencyObject) regionTarget, regionManager);
RegionManager.SetRegionName((DependencyObject) regionTarget, regionName);
}
}
}
As you can see, this is a very simple extension method that extends the IRegionManger interface. Inside, I simply set the region manager and the region name on the desired UI element.
This solution is very simple, still it works fine (at least for me). If you have any troubles with it, let me know.
Wednesday, February 18, 2009
WPF Wizard Control - Part II
In my previous post about rolling your own WPF wizard control, I've described how one can easily create simple, styleable wizard in WPF. Generally, I blogged that the wizard consists of two things, namely
Besides the collection of pages, the Wizard had two properties, namely
After coding this solution I realized there's a problem with it - the only wizard page that is the part of the wizard's logical tree is the page being displayed! This meant that DataContext property wasn't set correctly, and binding to controls across wizard pages was not possible.
A better Solution
Fortunately, it is very easy to overcome these problems, even without modifying wizard's template! My first assumption about wizard's base class was mistaken, because wizard is indeed a control that should have a content - its own pages :) And because there can be more than one page, the choice is obvious - ItemsControl.
Inheriting from ItemsControl reduced the following code from the Wizard class:
This was actually the ugly code that attached the value of Wizard's DataContext property to each wizard's page DataContext which eliminated the problem no. 1. And because now wizard contains all the pages within its Items collection (which can be databound via ItemsSource property), all pages appear in the wizard's logical tree. Thus, problems described earlier in this post no more exist :)
Because now I used ItemsControl, I could virtually put anything in the wizard and it will compile. But the wizard expects to contain instances of WizardPage class, so I needed to tell the wizard that it need to wrap any content that is not a WizardPage into an instance of WizardPage. This is done using the following code:
Note, however, that in this solution, both ActivePageIndex and ActivePage properties still play vital role. Also note that there is not a single change in the Wizard's template, which is very simple. The one problem with it is that it defines the "view" for the wizard and for the wizard's page. This will be fixed in the third release :)
I will blog about better approach to implementing custom WPF wizard which fixes the complexity of using the two mentioned properties and uses separate templates for the wizard and its pages in my next post, so stay tuned ;)
The code for this post can be downloaded from here. Note that it actually contains three Wizard's implementations. The one described in this post is contained within WpfWizard2 project. WpfWizard3 will be subject of my next post.
- Wizard class - representing the wizard with its buttons (Next, Previous, Finish, etc.) and simple behavior concerned around managing which wizard page should be displayed,
- WizardPage class - representing a container for a single wizard page.
1 2 ///
3 /// Wizard pages collection.
4 ///
5 public class WizardPagesCollection : ObservableCollection<WizardPage>
6 { 7 8 }Besides the collection of pages, the Wizard had two properties, namely
- ActivePageIndex - the index of the current page in the collection being displayed,
- ActivePage - the active page itself.
After coding this solution I realized there's a problem with it - the only wizard page that is the part of the wizard's logical tree is the page being displayed! This meant that DataContext property wasn't set correctly, and binding to controls across wizard pages was not possible.
A better Solution
Fortunately, it is very easy to overcome these problems, even without modifying wizard's template! My first assumption about wizard's base class was mistaken, because wizard is indeed a control that should have a content - its own pages :) And because there can be more than one page, the choice is obvious - ItemsControl.
Inheriting from ItemsControl reduced the following code from the Wizard class:
1 2 private WizardPagesCollection m_WizardPages;
3 4 ///
5 /// Returns a collection of wizard's pages.
6 ///
7 public WizardPagesCollection WizardPages
8 {9 get { return m_WizardPages; }
10 set
11 {12 m_WizardPages = value;
13 m_WizardPages.CollectionChanged += OnWizardPagesChanged; 14 } 15 } 16 17 private void OnWizardPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
18 {19 // This code glues all wizard's pages to wizard's DataContext.
20 // This is done due to the fact that when pages are switched, the
21 // page that is hidden looses its data context.
22 foreach (var page in WizardPages)
23 {24 var binding = new Binding("DataContext") { Source = this };
25 BindingOperations.SetBinding(page, DataContextProperty, binding);
26 } 27 }This was actually the ugly code that attached the value of Wizard's DataContext property to each wizard's page DataContext which eliminated the problem no. 1. And because now wizard contains all the pages within its Items collection (which can be databound via ItemsSource property), all pages appear in the wizard's logical tree. Thus, problems described earlier in this post no more exist :)
Because now I used ItemsControl, I could virtually put anything in the wizard and it will compile. But the wizard expects to contain instances of WizardPage class, so I needed to tell the wizard that it need to wrap any content that is not a WizardPage into an instance of WizardPage. This is done using the following code:
1 protected override DependencyObject GetContainerForItemOverride()
2 {3 return new WizardPage();
4 } 5 6 protected override bool IsItemItsOwnContainerOverride(object item)
7 {8 return item is WizardPage;
9 }Note, however, that in this solution, both ActivePageIndex and ActivePage properties still play vital role. Also note that there is not a single change in the Wizard's template, which is very simple. The one problem with it is that it defines the "view" for the wizard and for the wizard's page. This will be fixed in the third release :)
I will blog about better approach to implementing custom WPF wizard which fixes the complexity of using the two mentioned properties and uses separate templates for the wizard and its pages in my next post, so stay tuned ;)
The code for this post can be downloaded from here. Note that it actually contains three Wizard's implementations. The one described in this post is contained within WpfWizard2 project. WpfWizard3 will be subject of my next post.
Tuesday, January 27, 2009
Hide a window instead of closing it in WPF
Hiding a window instead of closing it is especially useful when the window is a singleton. This is a typical situation for "options" windows which store application settings. Balaji Ramesh proposed solution to this problem, which can be found here.
As you can see, the code is extremely simple. Everything it does is to subscribe to Window's Closing event (which is not a routed one), suppress the close action and invoke Window's Hide() method in the UI thread to actually hide the window. We could augment this code with Hiding and Hidden routed events to inform interested entities the window is hiding and when the window is hidden. Using Hiding event it's very easy to cancel window hiding as well.
But what would you do if you had dozens of windows which you would hide instead of close? Typing this code into every window constructor is by no means an option. The neat solution (at least in my opinion) is to implement this functionality as an Attached Behavior.
The core concept behind the above implementation is to subscribe to the Window's Close event inside HideInsteadClose attached property's change callback. Besides, we can implement Hiding and Hidden attached routed events. (this has been omitted for clarity). Using this code is as simple as adding appropriate code as Window's attribute in XAML as follows:
The code is available for download from my Code Gallery here.
1 2 // Handle closing event to hide window instead of closing it
3 Closing += delegate(object sender, CancelEventArgs e)
4 {5 e.Cancel = true;
6 7 Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
8 (DispatcherOperationCallback)(arg =>
9 { 10 Hide();11 return null;
12 }), null);
13 };As you can see, the code is extremely simple. Everything it does is to subscribe to Window's Closing event (which is not a routed one), suppress the close action and invoke Window's Hide() method in the UI thread to actually hide the window. We could augment this code with Hiding and Hidden routed events to inform interested entities the window is hiding and when the window is hidden. Using Hiding event it's very easy to cancel window hiding as well.
But what would you do if you had dozens of windows which you would hide instead of close? Typing this code into every window constructor is by no means an option. The neat solution (at least in my opinion) is to implement this functionality as an Attached Behavior.
1 public static readonly DependencyProperty HideInsteadCloseProperty =
2 DependencyProperty.RegisterAttached("HideInsteadClose",
3 typeof(bool), typeof(WindowBehavior), new FrameworkPropertyMetadata(
4 new PropertyChangedCallback(OnHideInsteadClose)));
5 6 7 private static void OnHideInsteadClose(DependencyObject d,
8 DependencyPropertyChangedEventArgs e)
9 {10 var window = d as Window;
11 if (window != null)
12 {13 if ((bool)e.NewValue)
14 {15 // Handle closing event to hide window instead of closing it
16 window.Closing += delegate(object sender, CancelEventArgs args)
17 {18 args.Cancel = true;
19 20 window.Dispatcher.BeginInvoke(DispatcherPriority.Background,
21 (DispatcherOperationCallback)delegate
22 {23 var cancelArgs = new CancelRoutedEventArgs(HidingEvent, window);
24 window.RaiseEvent(cancelArgs); 25 26 if (!cancelArgs.Cancel)
27 { 28 window.Hide();29 window.RaiseEvent(new RoutedEventArgs(HiddenEvent, window));
30 } 31 32 return null;
33 }, null);
34 }; 35 } 36 }37 }
The core concept behind the above implementation is to subscribe to the Window's Close event inside HideInsteadClose attached property's change callback. Besides, we can implement Hiding and Hidden attached routed events. (this has been omitted for clarity). Using this code is as simple as adding appropriate code as Window's attribute in XAML as follows:
Common:WindowBehavior.HideInsteadClose="True" Common:WindowBehavior.Hidden="HiddenHandler"
The code is available for download from my Code Gallery here.
Monday, January 19, 2009
Mammoth Pattern Miner - cool WPF application from AGH Department of Computer Science
I'm very excited to announce that a few days ago my university's Department of Computer Science has released the first version of Mammoth Pattern Miner 2009 (MPM), an application I'm currently actively developing (not alone of course :) ). The MPM is a data mining application that is able to analyze large amount of data and discover frequent sets and sequences, partial frequent sets and some user defined patterns. It uses some well known data mining algorithms as well as some custom implementations. Of course, it provides rich visualization capabilities, many filters and extensible application architecture (by the way, which application is not extensible nowadays :P ).
Here are some screen shots from the current release (click image to enlarge it). I'll try to post a video showing the system in action when I have a little free time.
Yet another visualization, tree this time :)
Mammoth Pattern Miner begun as an application that accompanied my master's thesis which has been developed during my stay at UTBM in France in 2008. After I graduated, I was given the opportunity to continue working on this project at my university. To cut the long story short, I simply accepted it.
Now, Mammoth is a mature software product which provides quite big functionality. Nevertheless, there's still much work to do ;)
Just in case you are curious, Mammoth uses Microsoft's .NET Framework 3.5 SP1, WPF and SQL Server 2005. It runs pretty fast on my Lenovo T61p laptop. However, big data sets require lots of ram.
Mammoth official site, for now available in polish only, is located at http://caribou.iisg.agh.edu.pl/proj/mammoth/. If you think you or your work might benefit from using this software, please email me.
Hope you liked it!
Here are some screen shots from the current release (click image to enlarge it). I'll try to post a video showing the system in action when I have a little free time.
Yet another visualization, tree this time :)Mammoth Pattern Miner begun as an application that accompanied my master's thesis which has been developed during my stay at UTBM in France in 2008. After I graduated, I was given the opportunity to continue working on this project at my university. To cut the long story short, I simply accepted it.
Now, Mammoth is a mature software product which provides quite big functionality. Nevertheless, there's still much work to do ;)
Just in case you are curious, Mammoth uses Microsoft's .NET Framework 3.5 SP1, WPF and SQL Server 2005. It runs pretty fast on my Lenovo T61p laptop. However, big data sets require lots of ram.
Mammoth official site, for now available in polish only, is located at http://caribou.iisg.agh.edu.pl/proj/mammoth/. If you think you or your work might benefit from using this software, please email me.
Hope you liked it!
Thursday, December 18, 2008
WPF Tips & Tricks Presentation
Yesterday, on Krakowska Grupa Deweloperów .NET, I gave a presentation, together with my friend Arkadiusz Świerczek, on latest Microsoft .NET Framework 3.5 SP1 WPF stuff and WPF Tips & Trick.
We didn't have enough time to cover all the goddies we've prepared, but we managed to introduce some basics around WPF and present WPF effects in pixel shader. Besides, we've presented how to write multi-language, runtime bound UI, skins and a rapid introduction to attached behaviors.
The presentation together with full sources can be downloaded from here. Enjoy!
We didn't have enough time to cover all the goddies we've prepared, but we managed to introduce some basics around WPF and present WPF effects in pixel shader. Besides, we've presented how to write multi-language, runtime bound UI, skins and a rapid introduction to attached behaviors.
The presentation together with full sources can be downloaded from here. Enjoy!
Saturday, November 29, 2008
patterns & practices: Composite WPF and Silverlight Drop 6
It's been couple of days since I started playing with Prism V2 Drop 6 (You can download it from here). Of course I've been using CompositeWPF aka Prism V1 for a longer time, and I must admin it's an excellent framework, but I wanted to see it's new Silverlight part. Here's what I've found so far.
In general, drop 6 seems working just fine. It contains the following features known from the WPF part:
As I previously said, everything is working fine. One thing disturbs me, however. On the very first version of Prism, I was able to use ordinary classes as views, the view was then defined as a data template. So I could have written something like that:
In this example, NavigationItemPresenter represents my custom button. However, there is no explicitly given view - the view is defined via data template. Unfortunately, from unknown reasons, this doesn't work in Silverlight. I receive NullPointerException. After "investigation" it turned out that internally, the view is casted to... DependencyObject!!! Why is that?! I don't known. I even tried to extend the DependencyObject class (yes, it's possible despite the fact many people say it's not), but I got other exceptions. To sum up, I use this release in my small project (small page for the product I'm currently working on, I'll post about it as soon as it's finished), but it's a pity that the cool approach with views defined using data templates doesn't work so far. Highly recommended.
In general, drop 6 seems working just fine. It contains the following features known from the WPF part:
- modularity
- event broker
- regions
As I previously said, everything is working fine. One thing disturbs me, however. On the very first version of Prism, I was able to use ordinary classes as views, the view was then defined as a data template. So I could have written something like that:
47 48 var downloadItemPresenter = m_Container.Resolve<NavigationItemPresenter>();
49 downloadItemPresenter.Text = "Download";
50 51 m_RegionManager.Regions[RegionNames.NavigationPanel].Add(downloadItemPresenter);
In this example, NavigationItemPresenter represents my custom button. However, there is no explicitly given view - the view is defined via data template. Unfortunately, from unknown reasons, this doesn't work in Silverlight. I receive NullPointerException. After "investigation" it turned out that internally, the view is casted to... DependencyObject!!! Why is that?! I don't known. I even tried to extend the DependencyObject class (yes, it's possible despite the fact many people say it's not), but I got other exceptions. To sum up, I use this release in my small project (small page for the product I'm currently working on, I'll post about it as soon as it's finished), but it's a pity that the cool approach with views defined using data templates doesn't work so far. Highly recommended.
Subscribe to:
Posts (Atom)




