Yay! The patch list for the Ajax Control Toolkit shows my two patches (for the dynamical adding of TabPanels to a TabContainer and the one for the zIndex of the PopupExtender) were 'applied in change set 54957'!

I don't know when the next official release of the ACT will be available, but you can always get the latest 'unstable' version (with the patches) here.

In order to customize controls the way you want, you can either use a DataTemplate, different specific ControlTemplate properties, use the properties that the controls publish, but in the end, to get it right, you must actually change the ControlTemplate of the control itself. The best practice is to use an external resource dictionary that contains a style that changes various properties and also, if needed, the ControlTemplate.

The problem there is that there is no way to partially change the control template. I mean, yeah, I could think of a few ways, but in the end is the same thing: you need to replace the control template completely. And now you have two ... err.. actually three problems.

First, there are ways of getting the default control template, with all the functionality (we are talking about one, two or even more pages of XAML) and change only what you want. It's not trivial, but it can be done, either by copying it from the published sources (like the Windows SDK or the Expression Blend SystemThemes folder) or by using a utility like ShowMeTheTemplate.

Second, there is the issue of control templates differing depending on the Windows theme. And therefore one must either accept that the application will only look one way for every theme and Windows operating system, or provide templates for all the themes available (there are 6 defaults and a generic fallback theme).

Now, there are many tutorials about how to do that, basically just create a Themes folder, change AssemblyInfo.cs to

[assembly: ThemeInfo(
ResourceDictionaryLocation.SourceAssembly, //where theme specific resource dictionaries are located
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
)]

, copy the xaml files (with certain names) there and change them as you see fit. There is a catch, though! This will only work on your custom controls. Default controls already have a template in the operating system theme, so you need to do one extra thing in order to overwrite them, and that is to write the following in the a parent control Resources block:

<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="{ThemeDictionary [LibraryOrApplicationNamespace]}" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

otherwise it will NOT work.

You can get the same result by adding this to the static constructor of the control, provided you have access to the sources:

DefaultStyleKeyProperty.OverrideMetadata(typeof([MyControlClass]), new FrameworkPropertyMetadata(typeof(MyControlClass)));


One thing you also need to be aware of is that Visual Studio caches the themes. If you change them, especially if you do it outside visual Studio, you need to force a Rebuild of the project.

I've decided to write this entry before I could actually master these tools because I don't think I will afterwards (I'd be too old to type). So here it goes:

  1. ReSharper - yes! I will probably need a ReSharper blog tag. This thing is good for everything! Its XAML smart intellisense is a gem, as well as the various options you get when writing WPF code or XAML
  2. Snoop - this is a very small tool that acts like a WPF FireBug. It can select an element, show properties, even change some of them
  3. Mole Visualizer - this is a Visual Studio debug visualizer, one that allows very detailed exploration of debugged objects, especially WPF elements
  4. XAML Power Tools - a Visual Studio addon, it allows a lot of stuff, like automatically generate the view from a model, extracting a style from a control, etc
  5. KaXaml - a tool that works like a XamlPad, but has more options. You basically use it as a poor man's Blend; and it's very light
  6. XamlPad - this is a Microsoft tool. Unfortunately, to use it you need to download the entire Windows SDK for Windows Server 2008 and .NET Framework 3.5, which is 1.5Gb in size
  7. Pistachio - this is a Visual Studio project resource browser. Give it the project and you can see the brushes, the style, the templates, the usages
  8. Expression Blend - the de facto Microsoft tool for editing XAML and working with design stuff. Not only it is not free, but it is also buggy. Unfortunately, I have a hunch I will have to use it in the near future to work with WPF styles
  9. ShowMeTheTemplate - Small application that explores the WPF default templates for various controls



All of the tools above, except ReSharper and Blend are free to use.

So I wasted 15 minutes on trying to make a converter work within a TemplateBinding. Even if there is no error returned, the converter is never called. Funny, no?

I was trying to bind a property to the value of a property of the parent UserControl in WPF. When you google for it you get something pretty interesting: give a name to the user control right inside the user control XAML, then reference it with ElementName.

What I found after hours of torment was that this doesn't always work. I guess it only works up to the first item container in the logical tree and then stops. So that when I tried to use a property ImageSource of the user control in a Menu.Icon it failed!

My solution looks pretty ugly, but it does work in all cases!


<Image Source="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Controls:MyUserControl}},Path=MainMenuImageSource}"
Width="16" Height="16"></Image>



In other words: find the ancestor of the type of your user control and use it as the RelativeSource of the binding.

Update: When I had more time to thing I realised that a MultiBinding needs a Converter, but a simple Binding also has a Converter and I guess that is what I should have used. I will update the post when I get to work on Monday.

I started to build the prototype of a control and I hit a wall where WPF binding was concerned.

For example: I wanted to bind my control to a collection of Items which could be Groups, Sections or Items. Groups have more Sections and Items. Sections have more Items, but they should be displayed as a non clickable section with its Item children under it. Everything in a menu.

At first I used an XML data source, which allowed me to use XPath to select all the Items in a Group, all the Sections and all the Items in the Section like this: XPath="Item|Section|Section/Item". However, when switching to an object schema, the normal Path syntax was too restrictive to allow for this. Even with a MultiBinding, I could find no Path syntax in which to select children of a certain type and their children. However! MultiBinding uses a Converter to usually merge two or more collections together. I used it to get the children and their own children! So forget XAML in this case, just use code:

public class SectionHeaderConverter:IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
List<ToolBarItem> list = new List<ToolBarItem>();
foreach (IEnumerable<ToolBarItem> collection in values)
{
foreach (ToolBarItem element in collection)
{
list.Add(element);
var toolBarSectionHeader = element as ToolBarSectionHeader;
if (toolBarSectionHeader != null)
{
foreach (var item in toolBarSectionHeader.Items)
{
list.Add(item);
}
}
}
}
return list;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}


This converter was then used in the XAML as the Converter for the MultiBinding:

<MultiBinding Converter="{StaticResource SectionHeaderConverter}">
<Binding Path="Items"/>
</MultiBinding>


Now, that fixed one issue, but how can I now make the different MenuItems to
  1. have different looks depending on type/attributes
  2. behave differently depending on type/attributes
but selectively, keeping the default style and datatemplate in other cases? At first, when I used the XML datasource, having an XPath to select the type of the node based on its name was not an option because the XAML XPath implementation does not allow for XPath functions! so I used a StyleSelector for the difference between Sections (unclickable, spanning the whole width of the menu strip) and normal menu items, then a DataTemplateSelector for the difference between Groups and Items. It is also here where I bound the MenuItem Click RoutedEventHandler to an EventHandler in the datasource item class.


<Menu
ItemsSource="{Binding ElementName=ToolBarCurrent,Path=Items}"
ItemContainerStyleSelector="{StaticResource MenuItemContainerStyleSelector}"
ItemTemplateSelector="{StaticResource MenuItemTemplateStyleSelector}"
></Menu>


I don't know if that is the best way to do it, but suddenly it was like a fog lifted from my eyes and instead of that dreaded XAML I had something I know and understand used in a simple fashion. It is beyond the scope of this post to show how specific implementations of the selectors above work, but there are two issues that I had to fix:
  • Since the styles were resources defined in the resources of the containing Grid, I had to find a way to reference the Grid object from the StyleSelector:
    This is done using the
    ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(container);
    var style = (Style) ic.FindResource("SectionStyle");
  • Since the data templates were resources defined in the resources of the containing Grid, I had to find a way to reference the Grid object from the DataTemplateSelector:
    this seems to be the same problem, but actually the solution was quite different, I used the FindVisualParent helper method like this:
    var ic = Helper.FindVisualParent<Grid>(container);
    The source for it is underneath.


public static TParentItem FindVisualParent<TParentItem>(DependencyObject obj)
where TParentItem : DependencyObject
{
DependencyObject current = obj;
while (current != null)
{
var tCurrent = current as TParentItem;
if (tCurrent != null)
return tCurrent;
current = VisualTreeHelper.GetParent(current);
}
return null;
}
.

Also, regarding this particular task, I found a way to display MenuItems grouped by a property in this blog post and at first I used this solution only to find out that this type of grouping only applies to flat DataTemplates. And while it seemed to be working in my first attempts with a HierarchicalDataTemplate, the grouping was only applied to the first level and not to the next.

My conclusion: as in many "magical" technologies, the complexity of a lot of problems is beyond the ability of the technology designers to predict. Therefore the only (and often enough, the best) option is to use your own code.

In Windows Presentation Foundation all resources (like ImageSources or Resource packs) are relative to the namespace of the control. So if you have a folder Images that holds your application icons and you use (in the application XAML) an ImageSource of "Images/MyImage.png" it will work. But as soon as the XAML is moved somewhere in a UserControl in the Controls namespace of a library, the ImageSource becomes invalid. It would only work as "../Images/MyImage.png" or "/Images/MyImage.png", even if the Controls namespace is not a folder and the control is in a library, not in the application that runs it!

This is part of a larger idea, that is Pack URIs. Pack URIs are used by the Open Packaging Conventions and are of the format pack://authority/path.


Long story short, authority can be application:/// or siteoforigin:///. The slashes at the end get escaped as commas in a pack URI so you get to have stuff like pack://application:,,,/ResourceFile.xaml. The path is more tricky: AssemblyShortName[;Version][;PublicKey];component/Path.
Attention at the component keyword. It is NOT a folder, but a keyword that must be there when referencing resources from an external library.

Example: I have the Resources/Images/image.png in a library and I want to use it in the XAML that is in the same library. The image source would be something like pack://application:,,,/libraryNameSpace;component/Resources/Images/image.png. Again look out for the component keyword.

Just yesterday I was struggling with the same issue, only this facette of it seems like a completely different bug. You see, I added this control to the library and everything worked fine EXCEPT the visual designer. It is known that the Visual Studio 2008 WPF designer is not the best possible piece of software, but this was one of those errors you don't know where it comes from.

So, let's take it from the beginning. I had something like
<HierarchicalDataTemplate DataType="{x:Type Code:League}" ItemsSource="{Binding Path=Divisions}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
Somewhere in the Window declaration there was a
xmlns:Code="clr-namespace:MyControls.Desktop.Code"
which is the namespace of the test application for the control in the library.
The application worked, but in the designer an error like "Type reference cannot find public type named 'League'.".

Many people gave the solution to remove the name of the assembly in the namespace declaration. So If I had something like "clr-namespace:MyControls.Desktop.Code;assembly=MyControls" and it was the current assembly, I should just remove it. Well, it wasn't the case here, was it?

In the end I found the solution here. You see, even if the assembly name was not specified, it was implied! And even if it was an application, not a library, it still was an assembly. And the Application name was... something with spaces in it!!

So, again, just go to the Project properties and change the Assembly name to not have spaces!

So, I had just wasted a long time being stupid about a user control, but I had finally fixed everything and I was willing to try it out. Initially I had tested it by directly entering it in XAML, but now I wanted to add it to the toolbox and drag and drop it to the WPF form.

First I got an error like "The following assemblies are installed SDK assemblies but could not be shown in the customize toolbox dialog because they are missing one or more components. Please make sure that all necessary libraries are available:" and then Microsoft.Ink.dll. It didn't seem to do anything bad, but I googled it anyway. It seems that a lot of people had this problem. The only solution was to actually close Visual Studio and then open it again. Other people reported more complicated issues like Visual Studio suddenly closing or showing a lot more libraries and doing it every time. This could help in that case: 363321. Choose Items in Toolbox causes Visual Studio 2008 SP1 to crash.
It also may be linked to the Visual Studio 2008 SDK, which I had recently installed.

Anyway, after that problem was solved, I proceeded on loading my WPF user control library by clicking Choose Items on a new Visual Studio toolbox tab and then browsing the DLL. Boom! "There are no components in 'something.dll' that can be placed on the toolbox.". That is because you must FIRST select the WPF Components tab in the Choose Items dialog, THEN click Browse. If you have Visual Studio 2005 you are out of luck, you don't even have the WPF components tab and the only way to do it is use the XAML editor.

Two short points I'd like to make about working with WPF in Visual Studio 2008:
  1. In order to see Binding errors, you need to open the Output window while the app is running, since any binding error is silently dropped, but displayed there. There is also a Binding property called FallbackValue which you can set to "ERRRROOOORRR!!" :)
  2. XML files are seldom unformatted or having weird spaces and extra lines. Yet, there is not context menu for XML editors like the Format in ASP.Net as*x files. However, the option (and many more) is available in the Edit -> Advanced menu.
    • Format entire document: Ctrl+K, Ctrl+D
    • Format selection: Ctrl+K, Ctrl+F
  3. Unfortunately, some of the useful commands are just set up in the Options menu, like what to do with extra lines. So go to Tools -> Options -> Text Editor -> XAML -> Formatting.
    • To set it so that the XML is auto formatted at completion of start/end tag or when pasting code, go to the General option
    • To get rid of extra empty lines, go to the Spacing option and choose either Collapse multiple empty lines in content to a single line or Remove empty lines in content

It can't be done. Maybe in XAML 2009. In the old one, it just fails. I am using ReSharper and it automatically finds the controls in XAML in the loaded libraries and creates the appropriate namespace. For a library called "My Controls" it adds an "assembly=My Controls" at the end of the clr-namespace and the compilation fails with "Unknown build error".

The only solution I could find for this is to rename the library so that it doesn't have spaces in it. In my case the library was actually another project and I changed the name in the project properties to have underscore rather than space.

What has gone into Siderite and made him rave mad? Is he high? Everybody knows that software patterns are all the rage and the only perfect and delicious way to make software. You can't just go "cowboy style" on software, it's an industry after all.

Well, I am not saying that (although you can probably guess from my impression of my virtual/inner critic that I am a bit partial to the cowboy approach). All I am saying is that once you identify a pattern (and yes, to open another parenthesis, a pattern is identified not learnt) one should never stoop low enough to use it. Some software should do that for him!

One good example is the Iterator Pattern. It sounds so grand, but the software implementation of it is the foreach command. Does anyone actually think while iterrating through a collection that they are using a pattern? As I said before, patterns are identified. You think of what you have been doing, see a pattern, make some software to take care of similar situations, then get on to identifying another pattern.

Well, yes, but you can't entrust everything to a software, Siderite! You will bloat your code, create tools that will do less than you wanted and still end up doing your own efficient code. I know, I've seen it before!

Well, thank you, critic! You have just identified a pattern! And any pattern should be solved. And yes, I agree that software can't do everything for you (yet!) and that sometimes the tools that are designed to help us with a problem become a problem themselves. But instead of having "two problems" you have a bad solution to a previous problem. Fixing the solution would fix everything and the problem domain is now one level of abstraction higher.

Stuff like managed code, linq, TDD, ORMs, log4net... just about every new technology I can think of, they are all solutions to patterns, stuff that introduces new problems on a higher level. What C# programmer cares about pointers anymore? (developers should still be aware of the true nature of pointers, but care less about it).

There is one final issue though, the one about the actual detection of patterns. Using "prediscovered" patterns like from the classic Gang of Four book or anything from Martin Fowler is ok, but only if they actually apply to your situation. That in itself shows you have to have a clear image of your activity and to be able to at least recognize patterns when you see them. Sometimes you do work that is so diverse or so slow that you don't remember enough of what you did in order to see there is a repetitive pattern. Or, worse, you do so much work that you don't have time to actually think about it, which I think is the death of every software developer. Well, what then?

Obviously a log (be it a web one or just a simple notebook or computer tracking system) would help. Writing stuff down makes one remember it better. Feeling the need to write about something and then remembering that you have already done so is a clear sign of a pattern. Now it is up to you to find a solution.

Back to the actual title of the post, I recognize there are situations where no automated piece of code can do anything. It's just too human or too complex a problem. That does mean you should solve it, just not with a computer tool. Maybe it is something you need to remember as a good practice or maybe you need to employ skills that are not technical in nature, but should you find a solution, think about it and keep thinking about it: can it be automated? How about now? Now? Now?

After all, the Romans said errare humanum est, sed perseverare diabolicum. The agile bunch named it DRY. It's the same thing: stop wasting time!

WPF Unleashed is a 2006 book in the Unleashed series about the new Microsoft paradigm on visual interaction, written by Adam Nathan. Windows Presentation Foundation is now the default Windows graphics framework, overriding Windows Forms, and it is based on XAML, which is used in Windows desktop applications, Silverlight applications, directly in Internet Explorer and even as a document template.

The book is nicely written, covering all the main characteristics of WPF, the functionality, the problems and tips on stuff that is not so clear. It also contains "Digging deeper" sections where some of the works "under the hood" are revealed. The book focuses more on the XAML implementation (the declarative part) rather that the code one, and I was happy to see that the code was written in C#.

All in all I liked the book and I wish I had more time to parse it completely. So far I've read the basic stuff (without the fancy graphics) so the first 10 chapters and I will wait for a moment of respite so I can detail some of the stuff I found in the book and how to implement them.

There are two things you need to do. First, set the project as having a neutral language. This is done in Visual Studio 2008 by going to the project's properties, selecting Application, clicking on Assembly information and setting the language. However, it doesn't set an UltimateResourceFallbackLocation. So you have to do it manually, by editing the Properties\AssemblyInfo.cs file and adding
[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)]


The second thing is rather dumb. I haven't found ANY way to do it from Visual Studio. I just edited the csproj file manually. It needs
<UICulture>en-US</UICulture>
set in (under, actually) every <PropertyGroup> in it.

What that does is create a language folder in the bin directory when compiled with a localizable resource file. Using the locBaml utility in the Windows SDK you can turn a resources.dll in the language folder into a CSV, then back into a dll like this:
LocBaml /parse ProjectName.g.en-US.resources /out:en-US.csv
LocBaml /generate ProjectName.resources.dll /trans:fr-CA.csv /cul:fr-CA
.

You will not find locBaml in the Windows SDK folder except maybe as a sample project. The sample project can be downloaded here. Don't forget to compile it!

Some other useful links:
WPF Localization
Localizing WPF Applications using Locbaml
LocBaml + MsBuild + ClickOnce Deployment

Rick Strahl presents an easier and better alternative by using normal resx files! I don't want to copy (too much) from his post, so just read it:
Resx and BAML Resources in WPF

and has 0 comments
I have seen this used in a couple of places, the most prominent being LInQ. You run a method and then you chain another method to it and so on and so on. It's a nice improvement in readability and a good alternative to static methods.

The clearest example I can give you is on Wikipedia. Check it out. It's actually very easy to use and implement.