How to Debug the Design Time Errors in WPF XAML File?

[Reblogged from How to Debug the Design Time Errors in WPF XAML File? thanks to Manish Dubeyy]

Introduction

While developing WPF applications, design view plays an important role not only placing the controls but also we can see the run time view at design time. How does it look like? It becomes frustrating when we see some design time errors and we cannot put a break point in XAML file to diagnose the error, moreover due to this single error sometimes, whole designer fails rendering other controls. So this article enables us to debug the design view of XAML documents in WPF.

Background

It is a pre-requisite that one should be familiar with basic WPF and most importantly one should know how to set design time data context. You can refer to other articles on CodeProject to know how to set a design time data context like this one.

Problem

While designing WPF applications, we frequently see the following types of error in our design view (See pic). Since XAML code does not allow us to insert a break point and debug the stuff, I will share a small trick to trap this error. (References are already there on the internet, but still developers are not so habituated to using it. The reason is that most of them don’t know it.)

ErrorPreview

Steps To Debug the Design Time Errors

  1. First of all, close all opened XAML documents in Visual Studio.
  2. Open the new instance of the same application in Visual Studio (say app2).
  3. Again, close all opened XAML documents. (To be on the safe side, you may close all documents in app2).
  4. Now open Task Manager just to verify whether XDesProc.exe must not be running. (Basically XDesProc.exeis responsible for debugging XAML files, so if any XAML documents are opened, then it launches automatically). So, if you find that XDesProc.exe is running (in Processes Tab), just kill it (right click on process and click on End Process Tree option).
  5. Now switch to app1 (original instance of Visual Studio in which you want break point to be hit). Now, open the file containing the design data view model (MainWindowViewModelDesignData.cs) and place a break point in the first line of its constructor.
  6. Switch to app2 again and open the View (i.e. MainWindow.xaml in which design time error is raising). It will launch the XDesProc.exe in Task Manager.
  7. Switch to app1 again, and go to Debug -> Attach to Processes… context menu item in Menu bar of Visual Studio.
  8. Search the XDesProc.exe and click on attach button.
  9. Switch to app2 and close and reopen the same XAML document (MainWindow.xaml). Once you do it, break point will get hit!2-Solve
  10. Here, you will find that you have not instantiated the PersonList property which is causingNullReference Exception in WPF Designer. After fixing it, you will see that now the designer is showing the data as well.3-DesignView

Points of Interest

For Visual Studio 2010 users, you will find devenv.exe in place of XDesProc.exe. Also, you can tweak with the exception settings if your break point does not becomes active (i.e., Go to Debug -> Exceptions settings -> Common Language RunTime Exceptions).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

WPF Design Time Resources Dictionary

[Reblogged from WPF Design Time Support (Part 2) thanks to jbe2277]

The WPF Designer works best if there is just one WPF project in the solution which is the application (exe) and so contains the App.xaml file. Then it will find all XAML resources that are necessary to render the views flawlessly. But in larger applications the views are often separated into different WPF projects (e.g. per module). In such a scenario the WPF designer is not able to find the resources defined or referenced in App.xaml anymore when this file resides in another project.

Microsoft introduced the Design-time Resources Dictionary file to overcome this issue. Blend is able to detect that some resources could not be resolved and asks us if we want to add a resource dictionary to use for displaying resources at design time.

blend-designtimeresources

Visual Studio uses this file as well but it is not able to create the file. If you want to create this file in Visual Studio then you have to create a Resource Dictionary (WPF). Use DesignTimeResources.xaml as file name and after creation move the file into the Properties folder in your project tree.

Now unload the project (Context menu of the project node in Solution Explorer). Then select Edit YourProject.csproj in the context menu of the unloaded project node. Search for the XML element that contains DesignTimeResources.xaml and replace it with the following XML snippet:

<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
  <Generator>MSBuild:Compile</Generator>
  <SubType>Designer</SubType>
  <ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>

Reload the project. The DesignTimeResource dictionary can be filled with MergedDictionaries. In the following example the merged dictionaries reside in another assembly. Thus, the long Source path is used.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/Waf.InformationManager.Common.Presentation;Component/Resources/ImageResources.xaml"/>
        <ResourceDictionary Source="/Waf.InformationManager.Common.Presentation;Component/Resources/ConverterResources.xaml"/>

This file will be ignored by the compiler. It does not have any effects on the running application. It is just used to improve the design time experience.

Web Browser Control – Specifying the IE Version

Thanks to Rick Strahl for this 🙂

http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version

Straight to the point:

Feature Delegation via Registry Hacks

Fortunately starting with Internet Explore 8 and later there’s a fix for this problem via a registry setting. You can specify a registry key to specify which rendering mode and version of IE should be used by that application. These are not global mind you – they have to be enabled for each application individually by writing a registry value for each specific EXE that is hosting the WebBrowser control.

This setting can be made for all users on local machine registry key or per user in the current user key of the registry.

For the Current User:

I’d recommend using the current user setting, as this setting can be made in one place and doesn’t require admin rights to write to the registry. This means you can actually make this change from within your application even if you don’t use an installer or run under an Admin account.

You do have to restart the app to see the change.

The key to write to is:

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

Value Key: DWORD  YourApplication.exe

Note that the FeatureControl and FEATURE_BROWSER_EMULATION keys may not exist at all prior to installation, so you may have to install that whole branch.

For all Users:

There are two different sets of keys for 32 bit and 64 bit applications.

64 bit or 32 bit only machine:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

Value Key: DWORD – YourApplication.exe

32 bit on 64 bit machine:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

Value Key: DWORD YourApplication.exe

The value to set this key to is (taken from MSDN here) as decimal values:

11001 (0x2AF9)
Internet Explorer 11. Webpages are displayed in IE11 Standards mode, regardless of the !DOCTYPE directive.

11000 (0x2AF8)
Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.

10001 (0x2711)
Internet Explorer 10. Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.

10000 (0x2710)
Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.

9999 (0x270F)
Internet Explorer 9. Webpages are displayed in IE9 Standards mode, regardless of the !DOCTYPE directive.

9000 (0x2328)
Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.

8888 (0x22B8)
Webpages are displayed in IE8 Standards mode, regardless of the !DOCTYPE directive.

8000 (0x1F40)
Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.

7000 (0x1B58)
Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.

The added key looks something like this in the Registry Editor:

RegistryEditorEmulation_2

Note that the 32 bit and 64 bit settings are significant depending on the type of application you are running. If you are running a 32 bit application on a 64 bit machine you need to use the Wow6432Node key to register this setting. If you’re running a 32 bit application on a 32 bit machine, or 64 bit application on a 64 bit application, then the standard registry key should be used.  This means if you’re installing a 32 bit application using an installer you probably will want to set both the Wow64 key and the regular key on the machine.

With this in place my Html Html Help Builder application which has wwhelp.exe as its main executable now works with HTML 5 and CSS 3 documents in the same way that Internet Explorer 9 does.

Incidentally I accidentally added an ‘empty’ DWORD value of 0 to my EXE name and that worked as well giving me IE 9 rendering. Although not documented I suspect 0 (or an invalid value) will default to the installed browser. Don’t have a good way to test this but if somebody could try this with IE 8 installed that would be great:

  • What happens when setting 9000 with IE 8 installed?
  • What happens when setting 0 with IE 8 installed?

Don’t forget to add Keys for Host Environments

If you’re developing your application in Visual Studio and you run the debugger you may find that your application is still not rendering right, but if you run the actual generated EXE from Explorer or the OS command prompt it works. That’s because when you run the debugger in Visual Studio it wraps your application into a debugging host container. For this reason you might want to also add another registry key for yourapp.vshost.exe on your development machine.

If you’re developing in Visual FoxPro make sure you add a key for vfp9.exe to see the rendering adjustments in the Visual FoxPro development environment.

WPF: ContentControl vs ContentPresenter

A small post to explain the little but important difference between ContentControl and ContentPresenter.

The most significant difference is that ContentPresenter has the ContentSource property while ContentControl hasn’t.

The ContentPresenter.ContentSource property specify which dependency property of the parent template instnace should be used to fill the ContentPresenter.Content.

For instance if you have a UserControl “MyControl” that defines a dependency property called  “MyProperty”, you can use the value of MyControl.MyProperty in the MyControl.Template in this way:

<ControlTemplate TargetType="MyControl">
      <StackPanel>
          <ContentPresenter ContentSource="MyProperty" />
      </StackPanel>
</ControlTempalte>

Instead using the ContentControl you could write the same template in this way:

<ControlTemplate TargetType="MyControl">
      <StackPanel>
          <ContentControl Content="{TemplateBinding MyProperty}" />
      </StackPanel>
</ControlTempalte>

In fact the ContentControl has a template that uses a ContentPresenter to show it’s own Content property using the ContentSource. The ContentPresenter is a light-weight component that is supposed to be used in a template as a simple place-holder for the Content property. The default value for the ContentPresenter.ContentSource is “Content”, so you just need to add an empty ContentPresenter in a template to let be the place-holder of the Content property of the template parent instance.

WPF: Attached Property in XAML Markup (The object ‘…’ already has a child and cannot add ‘…’)

Let’s say you need an attached property to set an arbitrary header content to any DependencyObject, to let you use that value and populate the Header property of any HeaderedContentControl, creating the class directly in your WPF test application:

public static class HeaderManager
{
	public static readonly DependencyProperty HeaderProperty = DependencyProperty.RegisterAttached(
		&quot;Header&quot;,
		typeof(object),
		typeof(HeaderManager),
		new PropertyMetadata(null));

	public static void SetHeader(DependencyObject element, object value)
	{
		element.SetValue(HeaderProperty, value);
	}

	public static object GetHeader(DependencyObject element)
	{
		return (object)element.GetValue(HeaderProperty);
	}
}

Then you want to attach that property to an UserControl that when injected in a TabItem can self declare it’s own header, and in first attempt you will end up trying to do this:

&lt;UserControl x:Class=&quot;RadicalTabRegion.Presentation.FirstView&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
             xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
             xmlns:s=&quot;clr-namespace:RadicalTabRegion.Presentation.Regions.Specialized&quot;
             mc:Ignorable=&quot;d&quot;
             d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;300&quot;&gt;

    &lt;s:HeaderManager.Header&gt;
        &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
            &lt;TextBlock Text=&quot;First View&quot;/&gt;
            &lt;CheckBox/&gt;
        &lt;/StackPanel&gt;
    &lt;/s:HeaderManager.Header&gt;

    &lt;Grid&gt;
        &lt;TextBlock Text=&quot;I'm the first view&quot;/&gt;
    &lt;/Grid&gt;

&lt;/UserControl&gt;

But if you try to compile this, you will get this error:

“The object ‘UserControl’ already has a child and cannot add ‘Grid’. ‘UserControl’ can accept only one child.”

This is because the compiler needs to know that HeaderManager.Header is an attached property, before compile xaml in baml, but because the HeaderManager class is declared in the same assembly of the xaml, it can’t. Actually I think this can be overcome by Microsoft, but never mind there’s a couple of solutions for that.

The first solution is to move the markup declaration after the first element in the UserControl content, and our case after the Grid:

&lt;UserControl x:Class=&quot;RadicalTabRegion.Presentation.FirstView&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
             xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
             xmlns:s=&quot;clr-namespace:RadicalTabRegion.Presentation.Regions.Specialized&quot;
             mc:Ignorable=&quot;d&quot;
             d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;300&quot;&gt;

    &lt;Grid&gt;
        &lt;TextBlock Text=&quot;I'm the first view&quot;/&gt;
    &lt;/Grid&gt;

    &lt;s:HeaderManager.Header&gt;
        &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
            &lt;TextBlock Text=&quot;First View&quot;/&gt;
            &lt;CheckBox/&gt;
        &lt;/StackPanel&gt;
    &lt;/s:HeaderManager.Header&gt;

&lt;/UserControl&gt;

The second solution is to move the HeaderManager class into a different class library, so in a different assembly, and this is the best approach because let you use the attached property more naturally, without incurring in that compile error even if you declare the property just before the UserControl.Content, that is more natural for an Header property. For instance if you add the class into a class library called “RadicalTabRegion.Windows.Presentation” you will end-up with this XAML that just works fine:

&lt;UserControl x:Class=&quot;RadicalTabRegion.Presentation.FirstView&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
             xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
             xmlns:s=&quot;clr-namespace:RadicalTabRegion.Windows.Presentation.Regions.Specialized;assembly=RadicalTabRegion.Windows.Presentation&quot;
             mc:Ignorable=&quot;d&quot;
             d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;300&quot;&gt;

    &lt;s:HeaderManager.Header&gt;
        &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
            &lt;TextBlock Text=&quot;First View&quot;/&gt;
            &lt;CheckBox/&gt;
        &lt;/StackPanel&gt;
    &lt;/s:HeaderManager.Header&gt;

    &lt;Grid&gt;
        &lt;TextBlock Text=&quot;I'm the first view&quot;/&gt;
    &lt;/Grid&gt;

&lt;/UserControl&gt;

This example is a part of an implementation I’m making for Radical to implement a TabControlRegion, that is able to inject a simple UserControl into a TabItem (generated at runtime) and let the developer deeply customize the TabItem.Header simply declaring the attached property directly into the UserControl. This is under development right now, and it is just one of the possible solutions, if I will like it, I will post the entire code, and pull a request for integrating the new region directly into Radical.