<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>emphess .NET &#187; WPF</title>
	<atom:link href="http://www.emphess.net/tag/wpf/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.emphess.net</link>
	<description>Christoph Menge&#039;s Blog</description>
	<lastBuildDate>Tue, 15 Jun 2010 00:50:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WPF Direct3D Interop</title>
		<link>http://www.emphess.net/2008/05/28/wpf_direct3d_interop/</link>
		<comments>http://www.emphess.net/2008/05/28/wpf_direct3d_interop/#comments</comments>
		<pubDate>Wed, 28 May 2008 11:49:10 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Direct3D]]></category>
		<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Overlay]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=38</guid>
		<description><![CDATA[There are some very interesting posts I missed the last days. Since .NET 3.5 SP1 perfectly integrates WPF with DirectX, a number of cool effects can finally be applied:
http://www.codeproject.com/KB/WPF/WPFPixelShader.aspx
http://blogs.msdn.com/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx
http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx
Some of those effects were on Dax Pandhi&#8217;s wish list for WPF (http://blog.nukeation.com/post/My-wishlist-for-the-next-release-of-WPF.aspx) for quite some time.
More importantly, the integration of WPF and Direct3D might eliminate the [...]]]></description>
			<content:encoded><![CDATA[<p>There are some very interesting posts I missed the last days. Since .NET 3.5 SP1 perfectly integrates WPF with DirectX, a number of cool effects can finally be applied:<br />
<a href="http://www.codeproject.com/KB/WPF/WPFPixelShader.aspx">http://www.codeproject.com/KB/WPF/WPFPixelShader.aspx</a></p>
<p><a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx">http://blogs.msdn.com/greg_schechter/archive/2008/05/12/introduction-to-writing-effects.aspx</a></p>
<p><a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx">http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx</a></p>
<p>Some of those effects were on Dax Pandhi&#8217;s wish list for WPF (<a href="http://blog.nukeation.com/post/My-wishlist-for-the-next-release-of-WPF.aspx">http://blog.nukeation.com/post/My-wishlist-for-the-next-release-of-WPF.aspx</a>) for quite some time.</p>
<p>More importantly, the integration of WPF and Direct3D might eliminate the need for a custom overlay control for the MenuKiller Control, which is a major performance hog (I currently use an overlay similar to this: <a href="http://blogs.msdn.com/pantal/archive/2007/07/31/managed-directx-interop-with-wpf-part-2.aspx">http://blogs.msdn.com/pantal/archive/2007/07/31/managed-directx-interop-with-wpf-part-2.aspx</a>).</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=WPF+Direct3D+Interop+http://bit.ly/9VFg7z" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/05/28/wpf_direct3d_interop/&amp;title=WPF+Direct3D+Interop" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/05/28/wpf_direct3d_interop/&amp;title=WPF+Direct3D+Interop" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/05/28/wpf_direct3d_interop/&amp;t=WPF+Direct3D+Interop" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/05/28/wpf_direct3d_interop/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A MenuKiller Control &#8211; Draft</title>
		<link>http://www.emphess.net/2008/05/04/a-menukiller-control-draft/</link>
		<comments>http://www.emphess.net/2008/05/04/a-menukiller-control-draft/#comments</comments>
		<pubDate>Sun, 04 May 2008 20:52:51 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[Differentiated UX]]></category>
		<category><![CDATA[DUX]]></category>
		<category><![CDATA[Menu Killer]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=37</guid>
		<description><![CDATA[This is just a draft on my upcoming article. I have asked a number of WPF Gurus to help me out on this&#8230;
Introduction

In an effort to take user experience to the next level, designers have come up with ideas on how to solve old problems in a new way. In the last few months, the [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a draft on my upcoming article. I have asked a number of <a href="http://wpfdisciples.wordpress.com/">WPF Gurus</a> to help me out on this&#8230;</p>
<h2>Introduction</h2>
<p>
In an effort to take user experience to the next level, designers have come up with ideas on how to solve old problems in a new way. In the last few months, the term &#8220;Differentiated User Experience&#8221; or simply &#8220;Differentiated UX&#8221; has come up to describe these efforts.
</p>
<p>
One of the beforementioned UI designers is Dax Pandhi, who published an article <a href="http://blog.nukeation.com/post/UX-Concepts---Rethinking-the-Button.aspx">&#8220;Rethinking the Button&#8221;</a> on <a href="http://blog.nukeation.com/default.aspx">his blog</a> which introduced a new control he calls <code>MenuKiller</code>. This control is certainly more than a replacement for the <code>Menu</code> and <code>ContextMenu</code>, as it can be used in ways that are quite different. However, it turns out that changing the way things are typically done is indeed not so easy.
</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/05/MenuKiller1.jpg" alt="A Screenshot of the MenuKiller" /></p>
<p>
This article gives an overview of my implementation of the <code>MenuKiller</code> and presents a small sample application. It&#8217;s written in C# using .NET 3.5 and Visual Studio 2008. What is presented here is not a full-fledged control, since there are quite a number of open todos. Yet, I hope that this motivates the use of different controls and serves as a good starting point for other WPF control development.
</p>
<p><span id="more-37"></span></p>
<h2>Download</h2>
<p>The current code can be <a href="http://www.emphess.net/wp-content/uploads/2008/05/MenuKillerDraft.zip">downloaded here</a>.</p>
<h2>Scope &amp; Prerequsities</h2>
<p>
Since this is a custom control which is meant to redefine significant parts of user experience, it is not trivial to implement. Hence, knowledge of WPF basics is helpful, but I attempted to present the basics while still giving some more advanced tips. Although this control is merely the result of my begginer&#8217;s journey into WPF, it took me quite some time to write and it involved a lot of reading, programming and experimenting.
</p>
<p>
Also, for a better explanation of the goal we try to achieve, I strongly recommend Dax&#8217;s article. While the screenshot should already give you an idea, the article provides significantly more insight.
</p>
<p>
This control uses a very different approach to control alignment. This is the most critical point of this article. Either I did this because I was completely lost and didn&#8217;t see a better solution or this approach is a necessity of the complicated arrange behaviour this control employs. I am quite happy with the last iteration of this, before I managed to cut down code size by almost 70% through refactoring. I also dropped some &#8216;heavy&#8217; features.
</p>
<h3>Design Aims</h3>
<ul>
<li> Using the control in XAML should be very similar to using a TreeView.</li>
<li> It should allow for rich and dynamic content, as well as animation.</li>
<li> Databinding must be possible.</li>
<li> Templating is also a requirement.</li>
<li> The importance of the Visual Studio designer is low.</li>
</ul>
<h3>Our Options</h3>
<p>
When reading the <a href="http://msdn2.microsoft.com/en-us/library/ms745025.aspx">MSDN on custom control authoring</a>, Microsoft presents a lot of options on how to avoid authoring a custom control. These options include Rich Content, Styles, Data Templates, Control Templates and Triggers. Microsoft does not directly encourage you to write a control, probably in an effort to prevent people from writing controls contrary to the idea of WPF. However, I have come to the conclusion that it is best for this control to use a custom control approach, despite -or even because of- the possibilities of WPF. This control is implemented with the idea in mind that you might want to create a control which does not come with source, yet can be customized easily.
</p>
<p>
Next, it is important not to re-invent the wheel, primarily because it is error-prone and the result might not fit into the framework as it should.
</p>
<p>
So what does our control do? Essentially, it shows a hierarchically organized collection of command-bound items circularly arranged around a center object.
</p>
<p>
That does, I agree, sound a little overcomplicated, but it is the full statement. Let&#8217;s see what we can get from it:</p>
<ul>
<li> Hierarchically organized: Since the control presents different &#8216;levels&#8217;, we need to model a hierarchy. This is reminiscent of a <code>TreeView</code>, obviously. <code>TreeView</code>s are derived from <code>ItemsControl</code>, so we might also want to take these into account. Note that <code>TreeView</code>s need container objects (<code>TreeViewItem</code>s) to store the hierarchy information while still allowing rich content.</li>
<li>Circularly arranged: Since this involves solely the arrangement of items, we might want to separate this problem into a custom panel, commonly called a CircularPanel.</li>
<li>around a center object: While this might look like a simple statement, it will prove to be one of the hardest tasks in the creation of our MenuKiller. Normal controls can have one of four alignments horizontally and vertically. These alignments are relative to their respective parent. The canvas, on the other hand, allows items to be positioned arbitrarily within its bounds.</li>
</ul>
<h2>The TreeView</h2>
<p>
A normal <code>TreeView</code> is an <code>ItemsControl</code>, which typically has <code>TreeViewItem</code>s. These are, again, <code>ItemsControl</code>s (or more specifically <code>HeaderedItemsControl</code>s), thereby representing the desired tree structure. For our control, however, the MenuKiller itself is not an <code>ItemsControl</code>: It can only have one root item. Therefore, it is a <code>ContentControl</code> and we will not derive from <code>TreeView</code>.
</p>
<p>
The <code>MenuKillerItem</code>s, on the other hand, are in fact <code>ItemsControl</code>s, thereby being a good candidate for the parent of our <code>MenuKillerItem</code>s. Although we won&#8217;t derive from <code>TreeView</code>, a small comparison of the two might be enlightening, yet keeping in mind that the behaviour of the MenuKiller is, not suprisingly, very similar to that of a normal <code>Menu</code> or <code>ContextMenu</code>.
</p>
<ul>
<li>While the TreeView is typically used for selection purposes, a MenuKiller is used for activation of actions. This can be a button press or -toggle, depending on the <code>CanExecute()</code> on the <code>Command</code></li>
<li>Unlike <code>TreeViewItem</code>s, Items in the MenuKiller cannot be selected. More importantly, nodes that have children are fundamentally different from those that haven&#8217;t, because they are used only for grouping purposes. (Note: It&#8217;s possible to do <a href="http://www.hardcodet.net/2008/03/prevent-wpf-tree-node-selection">grouping with TreeViews</a>, too, but that is not their default behaviour.</li>
<li>Most <code>TreeView</code>s are embedded in a scroll container, a MenuKiller on the other hand must not live in a scroll container. It also has a much tighter constraint in terms of item count.</li>
</ul>
<p>
It is obvious that the difference between the two is rather large. I also implemented an approach using <code>Menu</code> and <code>MenuItem</code>s, which have a very similar behaviour, but it turned out to be very ugly due to some render-related problems with the <code>MenuItem</code>s.
</p>
<h2>Sizing &#038; Positioning</h2>
<p>
The control works in a very visual manner, which requires us to have the root item in close proximity to the object it shall operate on. Let&#8217;s first concentrate on the case where the actual object does not move. Now we are still facing the problem that the control, when collapsing / expanding, changes its size. When the control grows to a certain direction -say, for example, to the top- it also needs to be repositioned, so the center of the main circle is still aligned with our object.</p>
<p>Even worse, since we have a hierarchical data structure, this problem must be solved for all items recursively. This, again, calls for a special panel. In an act of desperation, I called this <code>ReferenceAlignPanel</code>, thus qualifying for the worst-class-names-ever-thought-of-2008-award. While the name of this control is really awkward, it&#8217;s behaviour is at least unusual, too:<br />
Given a set of controls that implement <code>ICustomAlignedControl</code>, it will ask the controls for their <code>AlignReferencePoint</code> and arrange the controls in a way such that all reference points coincide. This, of course, is not possible in every case. I stuck to a very basic implementation of this kind of panel. More on that later.</p>
<p>The standard <code>ContextMenu</code> will be placed in a <code>Popup</code>, and can draw on areas of the screen where the application window is not. That sounds tempting for the MenuKiller, too. However, the <code>ContextMenu</code> can do that only due to the fact that the <code>ContextMenu</code> is a very boring control with a solid background color. The MenuKiller, having a 100% transparent panel, should not cross window borders. The effect might be visually irritating. </p>
<p>Apart from the alignment of circles, it would be nice to see a different expanding behaviour if the control is located at a window border. It is also desireable to make a distinction between left-to-right and right-to-left systems. I call this feature &#8220;adaptive arrange&#8221;, but the current solution does not include it because some problems remain to this day. (The issue here is that we need arrangement information in the measure pass. That is not good, and the current simple MenuKiller already needs remeasures from time to time).
</p>
<p>
Summing up the possibilities on arrangement:</p>
<ul>
<li>We can rearrange the items in the <code>CircularPanel</code> in a smart manner, thus eliminating the need to use alignment hacks. This is tricky and will only work to a certain degree.</li>
<li>We can put the whole MenuKiller or all <code>MenuKillerItem</code>s into a <code>Popup</code>, which might result in more available space at the cost of visual coherence. This doesn&#8217;t eliminate the arrangement problem at screen borders, however. Putting each item into a separate popup is not a good idea from my experience.</li>
</ul>
<p>
For most scenarios, we can make some simplifying assumptions. The most important assumption is that there is enough space in one direction, at least. So we can choose the direction(s) with most space available as initial grow directions. We might also accept the case where the control &#8216;jumps&#8217; because it grew too large in one direction, therefore requiring to be realigned, at least if there is little space available.
</p>
<h3>Custom Alignment: ICustomAlign</h3>
<p>Let&#8217;s talk about the way our custom alignment should look for the MenuKiller: When we talk about the center of a control, we normally mean the point which lies in the middle of the actual control&#8217;s border. However, for the CircularPanel, it is desirable to know the center of the circle segment. We have to provide some public getter:</p>
<pre lang="csharp">
/// <summary>
/// This name is too generic and imprecise.
/// </summary>
interface ICustomAlignedControl
{
  Point AlignReferencePoint { get; }
}
</pre>
<p>
Notice that this point may be well outside of the control. The screenshot shows a <code>CircularPanel</code> with its full circle, the circles center and the controls center:
</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/05/Alignment1.jpg" alt="Screenshot showing the difference between the center of the CircularPanels' desired size and the center of the corresponding circle segment." /></p>
<p>
Since we don&#8217;t want to mess around with this interface and its alignment-implications everywhere, it&#8217;s time for the first custom panel of the solution which takes care of that:
</p>
<h3>The ReferenceAlignPanel</h3>
<p>
Also known as the panel with the ugly name, the <code>ReferenceAlignPanel</code> constitutes the core concept that addresses the alignment issues we are getting into by arranging all its items such that their <code>AlignReferencePoints</code> or their centers coincide (see above). Let me give a short introduction to panels:
</p>
<p>
When writing a custom panel, one must override the <code>MeasureOverride</code> and <code>ArrangeOverride</code> methods, which constitute the 2-pass layout system of WPF. In the <code>MeasureOverride()</code> method, the control is asked for its <code>DesiredSize</code>. WPF will automatically assign the return value of the measure pass to the <code>DesiredSize</code>-property. Note that even if the amount of <code>availableSize</code> is infinite (as it is for example in a scroll-container), you must not return an infinite size from <code>MeasureOverride</code>. Also, we need to make sure we call <code>Measure()</code> on all children:
</p>
<pre lang="csharp">
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MenuKiller
{
  public class ReferenceAlignPanel : Panel, ICustomAlignedControl
  {
    private Point _alignReferencePoint;

    public Point AlignReferencePoint
    {
      get { return _alignReferencePoint; }
      set { _alignReferencePoint = value; }
    }

    private Vector GetChildOffset(UIElement child)
    {
      Vector childDesiredOffset;

      if (child is ICustomAlignedControl)
      {
        childDesiredOffset = AlignReferencePoint -
                                    ((ICustomAlignedControl)child).AlignReferencePoint;
      }
      else
      {
        // TODO: Honor the children's align properties
        childDesiredOffset = new Vector();

        childDesiredOffset.X =
            _alignReferencePoint.X - child.DesiredSize.Width * 0.5;
        childDesiredOffset.Y =
            _alignReferencePoint.Y - child.DesiredSize.Height * 0.5;
      }

      if (AllowRealign)
      {
        // If this happens, we have to re-measure all items!
        if (childDesiredOffset.X < 0)
        {
          _alignReferencePoint.X -= childDesiredOffset.X;
          childDesiredOffset.X = 0;
          realignRequired = true;
        }

        if (childDesiredOffset.Y < 0)
        {
          _alignReferencePoint.Y -= childDesiredOffset.Y;
          childDesiredOffset.Y = 0;
          realignRequired = true;
        }
      }

      return childDesiredOffset;
    }

    bool realignRequired = false;

    protected override Size ArrangeOverride(Size finalSize)
    {
      int arrangeCount = 0;

      // realign should not be required, but you can't bet on it.
      // Protect from infinite iteration.
      do
      {
        foreach (UIElement child in Children)
        {
          if (child.IsVisible)
          {
            Vector childOffset = GetChildOffset(child);

            child.Arrange(
              new Rect(childOffset.X,
                       childOffset.Y,
                       child.DesiredSize.Width,
                       child.DesiredSize.Height));
          }
        }

        ++arrangeCount;
      } while (realignRequired &#038;&#038; arrangeCount < 2);

      return finalSize;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
      Size inifiniteSize =
            new Size(Double.PositiveInfinity, Double.PositiveInfinity);

      AdjustAlignReferencePoint(availableSize);

      bool bMeasureNecessary = true;
      int iMaxRemeasureCount = 4;

      Size neededSize = new Size();

      // ugly and convoluted
      // A high number of remeasures will not happen - except
      // for the vs designer, it seems. Removing
      // this check will crash VS
      // FIXME: Clean this up or use different beh. in design mode
      for (int i = 0; bMeasureNecessary &#038;&#038; i < iMaxRemeasureCount; ++i )
      {
        neededSize.Width = neededSize.Height = 0;

        bMeasureNecessary = false; // Assume remeasure is not needed

        Vector MinimumChildOffset =
          new Vector(Double.MaxValue, Double.MaxValue);

        foreach (UIElement child in Children)
        {
          child.Measure(inifiniteSize);

          if (child.IsVisible == false)
          {
            continue;
          }

          Vector childDesiredOffset = GetChildOffset(child);

          MinimumChildOffset.X =
            Math.Min(MinimumChildOffset.X, childDesiredOffset.X);

          MinimumChildOffset.Y =
            Math.Min(MinimumChildOffset.Y, childDesiredOffset.Y);

          neededSize.Width = Math.Max(neededSize.Width,
                        childDesiredOffset.X + child.DesiredSize.Width);
          neededSize.Height = Math.Max(neededSize.Height,
                        childDesiredOffset.Y + child.DesiredSize.Height);
        }

        if (bMeasureNecessary)
          continue;

        if (AllowRealign)
        {
          if (MinimumChildOffset.X > 0)
            _alignReferencePoint.X -= MinimumChildOffset.X;

          if (MinimumChildOffset.Y > 0)
            _alignReferencePoint.Y -= MinimumChildOffset.Y;

          if (MinimumChildOffset.X > 0 || MinimumChildOffset.Y > 0)
          {
            bMeasureNecessary = true;
          }
        }
      }

      return neededSize;
    }

#if DEBUG
    protected override void OnRender(DrawingContext dc)
    {
      base.OnRender(dc);

      Rect r = new Rect(this.DesiredSize);

      dc.DrawRectangle(null, new Pen(Brushes.Tomato, 2.0), r);

      // show the visual center
      dc.DrawEllipse(Brushes.SeaGreen, null, _alignReferencePoint, 3, 3);
    }
#endif
  }
}
</pre>
<p>
As you can see, there are some hacks in here: We sometimes need to repeat measurement. We will later dig into that deeper; there are a number of unusual effects here.
</p>
<h3>Implementing a CircularPanel</h3>
<p>
The CircularPanel will arrange all items (more specifically, their centers or their align reference points) on a circle segment. The segments <code>StartAngle</code>, <code>EndAngle</code> and <code>Radius</code> can be customized using <code>DependencyProperties</code>, which automatically enables data binding and animation:
</p>
<pre lang="csharp">
#region Dependency Properties
#region StartAngle DP
[Category("Arrange")]
[Description(@"Sets the angle in degrees where the first item will
    be placed. 0 degrees points to the top.")]
public double StartAngle
{
    get { return (double)GetValue(StartAngleProperty); }
    set { SetValue(StartAngleProperty, value); }
}

public static readonly DependencyProperty StartAngleProperty =
    DependencyProperty.Register("StartAngle", typeof(double), typeof(CircularPanel),
    new FrameworkPropertyMetadata(45d,
        FrameworkPropertyMetadataOptions.AffectsArrange));
#endregion

#region EndAngle DP
[Category("Arrange")]
[Description(@"Sets the angle in degrees where the last item will be placed. 0 degrees
    points to the top. Note that this will be ignored if AngleSpacing is specified.")]
[TypeConverterAttribute(typeof(DoubleAutoConverter))]
public double EndAngle
{
    get { return (double)GetValue(EndAngleProperty); }
    set { SetValue(EndAngleProperty, value); }
}

public static readonly DependencyProperty EndAngleProperty =
    DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularPanel),
    new FrameworkPropertyMetadata(Double.NaN,
        FrameworkPropertyMetadataOptions.AffectsArrange));
#endregion

#region Radius DP
[Category("Arrange")]
[Description(@"Sets the radius of the circle where children will be positioned on.
    Note that the resulting panel might be siginificantly larger.")]
public double Radius
{
    get { return (double)GetValue(RadiusProperty); }
    set { SetValue(RadiusProperty, value); }
}

public static readonly DependencyProperty RadiusProperty =
    DependencyProperty.Register("Radius", typeof(double), typeof(CircularPanel),
        new FrameworkPropertyMetadata(45d,
            FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion

#region AngleSpacing DP
[Category("Arrange")]
[Description(@"Sets the number of degress between two items. When
    set to 'auto', children will be arranged evenly distributed between
    StartAngle and EndAngle.")]
[TypeConverterAttribute(typeof(DoubleAutoConverter))]
public double AngleSpacing
{
    get { return (double)GetValue(AngleSpacingProperty); }
    set { SetValue(AngleSpacingProperty, value); }
}

public static readonly DependencyProperty AngleSpacingProperty =
    DependencyProperty.Register("AngleSpacing", typeof(double),
        typeof(CircularPanel),
        new FrameworkPropertyMetadata(45d,
            FrameworkPropertyMetadataOptions.AffectsArrange));
#endregion
#endregion
</pre>
<p>
For the CircularPanel, the <code>MeasureOverride()</code> method looks like this:
</p>
<pre lang="csharp">
protected override Size MeasureOverride(Size availableSize)
{
  Size size = new Size(Double.PositiveInfinity, Double.PositiveInfinity);
  Size resultSize = new Size();

  if (this.Children == null || this.Children.Count == 0)
  {
      return resultSize;
  }

  RecalcParams();

  int iCurrentChildIndex = 0;

  dXMax = Double.MinValue;
  dYMax = Double.MinValue;

  dXMin = Double.MaxValue;
  dYMin = Double.MaxValue;

  foreach (UIElement child in Children)
  {
    double dAngle = ((double)(iCurrentChildIndex)) * dRenderAngleSpacing
    		    + StartAngle;

    double dX =  dRenderRadius * Math.Sin(dAngle * dDegToRad);

    // We invert the Y coordinate, because the origin in controls
    // is the upper left corner, rather than the lower left
    double dY = -dRenderRadius * Math.Cos(dAngle * dDegToRad);

    child.Measure(size);

    Point visualCenter = new Point();

    if (child is ICustomAlignedControl)
    {
      ICustomAlignedControl mkchild = (ICustomAlignedControl)child;
      visualCenter.X = mkchild.AlignReferencePoint.X;
      visualCenter.Y = mkchild.AlignReferencePoint.Y;
    }
    else
    {
      visualCenter.X = child.DesiredSize.Width * 0.5;
      visualCenter.Y = child.DesiredSize.Height * 0.5;
    }

    dXMax = Math.Max(dXMax, dX + (child.DesiredSize.Width - visualCenter.X));
    dYMax = Math.Max(dYMax, dY + (child.DesiredSize.Height - visualCenter.Y));

    dXMin = Math.Min(dXMin, dX - (visualCenter.X));
    dYMin = Math.Min(dYMin, dY - (visualCenter.Y));
    iCurrentChildIndex++;
  }

  resultSize.Width = dXMax - dXMin;
  resultSize.Height = dYMax - dYMin;

  return resultSize;
}

private Vector GetChildOffset(UIElement child, double dAngle)
{
  Vector Offset = new Vector();

  if (child is ICustomAlignedControl)
  {
    ICustomAlignedControl mkchild = (ICustomAlignedControl)child;
    Offset.X =  dRenderRadius * Math.Sin(dAngle * dDegToRad)
    		- dXMin - mkchild.AlignReferencePoint.X;
    Offset.Y = -dRenderRadius * Math.Cos(dAngle * dDegToRad)
    		- dYMin - mkchild.AlignReferencePoint.Y;
  }
  else
  {
    Offset.X =  dRenderRadius * Math.Sin(dAngle * dDegToRad)
    		- dXMin - child.DesiredSize.Width * 0.5;
    Offset.Y = -dRenderRadius * Math.Cos(dAngle * dDegToRad)
    	 	- dYMin - child.DesiredSize.Height * 0.5;
  }

  return Offset;
}
</pre>
<p>
First of all, note that the maximum and minimum X and Y coordinates will be used to determine the size of the resulting control. The idea here is that the CircularPanel does not need to be large enough for a full circle. You might even choose to use the CircularPanel in a different context with very large radius to achieve a completely different effect:
</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/05/CircularPanel1.jpg" alt="CircularPanel Screenshot" /></p>
<p>
Note the border which is, as promised, only as large as necessary to hold the children. The circle segment which is visible is a little debugging helper. Let&#8217;s add these fancy lines and circles to the <code>OnRender()</code> method:
</p>
<pre lang="csharp">
#if DEBUG
protected override void OnRender(DrawingContext dc)
{
    base.OnRender(dc);

    System.Windows.Media.Pen p =
        new System.Windows.Media.Pen(System.Windows.Media.Brushes.LightBlue, 2.0);

    dc.DrawRectangle(null, p, new Rect(0, 0,
        DesiredSize.Width - Margin.Left - Margin.Right,
        DesiredSize.Height - Margin.Top - Margin.Bottom));

    dc.DrawEllipse(null, p, AlignReferencePoint, dRenderRadius, dRenderRadius);
    dc.DrawEllipse(null, p, AlignReferencePoint, 1.0, 1.0);
}
#endif
</pre>
<p>
A note on this one: Using the <code>DesiredSize</code>, we can determine and debug whether our measure method works as expected. However, when clipped, this value will not decrease, so the border will just be clipped partially just like the rest of the control. Sice <code>DesiredSize</code> includes <code>Margin</code>, we have to subtract the value if we want to see the minimum size in this case. You also may want to draw additional <code>Rect</code>s for debugging purposes, namely:</p>
<ul>
<li><code>Rect r = LayoutInformation.GetLayoutSlot(this);</code> This is all available space (might be larger or smaller than <code>DesiredSize</code>) including <code>Margin</code></li>
<li><code>RenderSize</code> This is all available space (again larger or smaller than <code>DesiredSize</code>), not including margin</li>
</ul>
<p>A simple CircularPanel in debug mode now looks like this:
</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/05/CircularPanel2.jpg" alt="Screenshot of a CircularPanel showing a full circle." /></p>
<p>
The CircularPanel provided here is still very simple, because it does not provide support realignment, re-scaling, different positioning modes, etc. However, adding that functionality is straightforward, and the panel is more elaborate than many others I found on the net. Furthermore, our CircularPanel makes some assumptions here, namely that it centers all children unless they implement the <code>ICustomAlignedControl</code> interface.
</p>
<h3>The MenuKillerItem</h3>
<p>
First, we have to decide whether we customize an existing control, create a <code>UserControl</code> or create a custom control. Since we need quite special behaviour and want the control to be re-templateable, we choose a custom control. When creating a custom control, there is no designer support (nonsense in this case, anyway) and the control will be derived from an existing control or a control base class, rather than from <code>UserControl</code>. A custom control will have a default template which is stored in <code>Themes/Generic.xaml</code>.
</p>
<p>
As previously mentioned, the <code>MenuKillerItem</code> will have to be an <code>ItemsControl</code> so it can hold a number of children. We also like it to have an <code>Expanded</code> property and a <code>Header</code>, so we derive this from <code>TreeViewItem</code>, where we get both of the last for free. With the components we have created before, we can start creating the core functionality of the future MenuKiller control within the <code>MenuKillerItem</code>. Since the whole MenuKiller has a recursive structure, most of the work is done in the <code>MenuKillerItems</code>, rather than in the <code>MenuKiller</code> class.
</p>
<p>
Additionally, we want the <code>MenuKillerItem</code> to report where its <code>Header</code> is positioned, so we have to implement <code>ICustomAlignedControl</code>, too.
</p>
<p>
Moreover, sticking to the approach which has a <code>Button</code> in its template, we need to assign a <code>Command</code> to the <code>MenuKillerItem</code>. In doing so, we expect the <code>MenuKillerItem</code> to be able to trigger that associated command. To do so, it needs to implement <code>ICommandSource</code>. Thus, our class defition reads:
</p>
<pre lang="csharp">
public class MenuKillerItem : TreeViewItem, ICommandSource, ICustomAlignedControl
{
  // ...
}
</pre>
<h4>Putting it together</h4>
<p>
The <code>MenuKillerItem</code> will consist of a <code>Button</code> which can be used to toggle expansion (a node), or to send a specific application command (a leaf), and a <code>CircularPanel</code>, which presents children if they exist and the <code>MenuKillerItem</code> is expanded. Since we want the Button to be in the center of the circle segment, we enclose both in a <code>ReferenceAlignPanel</code>, which does all the hard work for us.
</p>
<p>
Sadly, we need to know these components in the code (Footnote: This is not entirely true, at least the <code>Button</code> can easily be removed. For this article, I chose the simpler option, though). Therefore, we have to introduce some kind of contract between the default template defined in <code>Generic.xaml</code> and the code. We do this by giving those controls a special name, per convention prefixed with <code>PART_</code>. Let&#8217;s have a look at the <code>MenuKillerItem</code>s default template:
</p>
<pre lang="xaml">
<!-- Some things stripped out -->
<ControlTemplate x:Key="MenuKillerItemTemplate"
                 TargetType="local:MenuKillerItem">
  <local:ReferenceAlignPanel x:Name="PART_AlignPanel" >
    <Button x:Name="PART_Button"
            Style="{StaticResource MenuKillerBtnStyle}">
      <ContentPresenter ContentSource="Header" />
    </Button>
    <local:CircularPanel x:Name="PART_Panel"
                         IsItemsHost="True"
                         Visibility="..." />
  </local:ReferenceAlignPanel>
</ControlTemplate>
</pre>
<p>
Let&#8217;s take a close look at this. The first line is trivial: It creates a <code>ControlTemplate</code> for the <code>MenuKillerItem</code>. (Applying the template, however, can be a little tricky. See <a href="http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/">my blog post on this</a>).
</p>
<p>
Everything in the control is then placed in a <code>ReferenceAlignPanel</code>, which will arrange the items in the desired fashion. Since we need to know this control in the code, we give it a <code>PART_</code>-prefix and call it <code>PART_AlignPanel</code>.
</p>
<p>
In the <code>ReferenceAlignPanel</code>, we place a <code>Button</code>, which we simply call <code>PART_Button</code> and apply a certain style to it. What the style looks like is not important right now. This merely makes sure the hover behaviour of the buttons is the same. As previously mentioned, the button does not need to be part of the generic template, but it simplifies using the control a little. Since we don&#8217;t want to restrict the contents of the button, we simply put a <code>ContentPresenter</code> in it which will put all content from the <code>TreeViewItem.Header</code> into it.
</p>
<p>
The <code>CircularPanel</code> is now added, again with <code>PART_</code>-prefix. Since we want all <code>TreeViewItem.Items</code> to appear in it, we set <code>IsItemsHost</code> to <code>true</code>. The <code>Visibility</code>, of course, shall depend on the <code>TreeView.IsExpanded</code> state. We&#8217;ll cover that later.
</p>
<p>
We have now created our default control template in <code>generic.xaml</code>, where the control has three <code>PART_</code>s. Here&#8217;s how we access them from code so we can use them later:</p>
<pre lang="csharp">
public override void OnApplyTemplate()
{
  base.OnApplyTemplate();

  mCenterButton = Template.FindName("PART_Button", this) as Button;

  if (null != mCenterButton)
  {
    mCenterButton.Click += new System.Windows.RoutedEventHandler(mCenterButton_Click);
    mCenterButton.MouseEnter += new MouseEventHandler(MenuKillerItem_MouseEnter);
  }

  mPanel = Template.FindName("PART_Panel", this) as CircularPanel;

  mAlignPanel = Template.FindName("PART_AlignPanel", this) as ReferenceAlignPanel;

  if (null != mPanel)
  {
    mPanel.ChildArranged += new CircularPanel.OnChildArranged(mPanel_ChildArranged);
  }
}
</pre>
<p>
An important note: Do not use <code>GetTemplateChild()</code>, because it will only find direct descendants. Also refer to the <a href="http://msdn2.microsoft.com/en-us/library/system.windows.frameworkelement.gettemplatechild.aspx">MSDN Comment of <code>GetTemplateChild()</code></a>. IntelliSense should also tell you that its use is deprecated. This is a common mistake and it severly limits the extensibility and customizeability of the control.
</p>
<p>
I introduced this section with &#8220;sadly&#8221;. Why that? Well, the problem with this kind of dependency is that is somewhat error prone and hidden. It also creates a very tight coupling. However, the reasons for this lie largely in the problem domain: We need these controls to exist, otherwise the control cannot implement the behaviour it is expected to. We can at least loosen the coupling a little by providing interfaces here, that is, we don&#8217;t require a <code>CircularPanel</code> for example, but only an <code>ICircularPanel</code> which can then be re-implemented by the control user. This enhances extensibility at little cost, but here, customization is going very far.
</p>
<p>
In order to enhance visibility of this contract, there is the <code>TemplatePart</code> attribute, which should be applied to the class:</p>
<pre lang="csharp">
[TemplatePart(Name = "PART_Button", Type = typeof(Button))]
[TemplatePart(Name = "PART_Panel", Type = typeof(CircularPanel))]
[TemplatePart(Name = "PART_AlignPanel", Type = typeof(ReferenceAlignPanel))]
public class MenuKillerItem : TreeViewItem, ICommandSource, ICustomAlignedControl
{
  // ...
}
</pre>
<p>
The attribute doesn&#8217;t change anything in terms of behaviour, but it adds meta information which is available to programs such as Expression Blend.
</p>
<p>
The code snippet above also shows the first reasons why we need to identify these controls: We want to be notified of <code>MouseEnter</code> and of <code>Click</code> events on the <code>Button</code>. The latter activates the command that is associated with this <code>MenuKillerItem</code>, or toggles expanson:
</p>
<pre lang="csharp">
void mCenterButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
  if (this.mPanel.Children.Count > 0)
  {
    MenuKillerCommands.OpenCategory.Execute(null, this);
  }
  else
  {
    if (Command != null)
    {
      RoutedCommand command = Command as RoutedCommand;

      if (command != null)
      {
        command.Execute(CommandParameter, CommandTarget);
      }
      else
      {
        ((ICommand)Command).Execute(CommandParameter);
      }
    }
  }
}
</pre>
<p>
Note that there are esentially two different ways to execute the <code>Command</code>, depending on its type. Also note that we also implement the expansion using a custom routed command. This is convenient, since there is little overhead but it improves extensibility by providing a mechanism to programatically trigger expansion from the outside.
</p>
<h4>Custom Commands</h4>
<p>
Declaring a custom command is very easy:
</p>
<pre lang="csharp">
public class MenuKillerCommands
{
  public static readonly RoutedUICommand ToggleExpansion =
        new RoutedUICommand("ToggleExpansion",
                            "ToggleExpansion",
                            typeof(MenuKillerCommands));
}
</pre>
<p>
However, we also need to create a <code>CommandBinding</code> in the static constructor of the <code>MenuKillerItem</code>:
</p>
<pre lang="csharp">
static MenuKillerItem()
{
  DefaultStyleKeyProperty.OverrideMetadata(typeof(MenuKillerItem),
      new FrameworkPropertyMetadata(typeof(MenuKillerItem)));

  CommandBinding binding = new CommandBinding(MenuKillerCommands.ToggleExpansion);
  binding.Executed += new ExecutedRoutedEventHandler(ToggleCommandHandler);
  binding.CanExecute += new CanExecuteRoutedEventHandler(CanToggleHandler);

  CommandManager.RegisterClassCommandBinding(typeof(MenuKillerItem), binding);
}

private static void ToggleCommandHandler(object target, ExecutedRoutedEventArgs e)
{
  if (null != target &#038;&#038; target is MenuKillerItem)
  {
    ((MenuKillerItem)target).ToggleExpand();
  }
}

private static void CanToggleHandler(object target, CanExecuteRoutedEventArgs e)
{
  if (null != target &#038;&#038; target is MenuKillerItem)
  {
    e.CanExecute = ((MenuKillerItem)target).CanToggleExpand();
  }
}
</pre>
<p>
The command then simply calls <code>ToggleExpand</code> on the target <code>MenuKillerItem</code>.
</p>
<h4>Expanding a Node</h4>
<p>
Now, what happens when we open a node? Essentially, we have to set the <code>TreeViewItem.Expanded</code> property. Databinding will the show the circular panel, and the <code>ReferenceAlignPanel</code> makes sure alignment is OK&#8230; But, wait a second, doesn&#8217;t that imply that the size of this control changes? Yes, but worst of all, this change propagates to the root of the tree:
</p>
<pre lang="csharp">
void InvalidateTreeMeasure()
{
  InvalidateMeasure();
  mPanel.InvalidateMeasure();
  mAlignPanel.InvalidateMeasure();

  if (Parent is MenuKillerItem)
  {
    ((MenuKillerItem)Parent).InvalidateTreeMeasure();
  }
}
</pre>
<h4>Measure and Arrange in the MKI</h4>
<p>
Fortunately, since the <code>ReferenceAlignPanel</code> and the <code>CircularPanel</code> do all the gritty work for us, the <code>MeasureOverride</code> of the <code>MenuKillerItem</code> is very simple:
</p>
<pre lang="csharp">
protected override Size MeasureOverride(Size constraint)
{
  // Beware of all this allocations, they are not necessary
  Size infSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);

  mCenterButton.Measure(infSize);

  mAlignPanel.AlignReferencePoint =
  	new Point(mCenterButton.DesiredSize.Width * 0.5,
  						mCenterButton.DesiredSize.Height * 0.5);

  mPanel.Measure(infSize);
  mAlignPanel.Measure(infSize);

  return base.MeasureOverride(constraint);
}
</pre>
<p>
There is not even an <code>ArrangeOverride</code>! However, when a new <code>MenuKillerItem</code> is opened, we might want to tell it which direction it should open to. Because we can&#8217;t get that information easily, we simply have the <code>CircularPanel</code> notify us about its arrangements. In <code>OnApplyTemplate</code>, we already registered to the event. Here comes the implementation:
</p>
<pre lang="csharp">
public override void OnApplyTemplate()
{
	// ...
  if (null != mPanel)
  {
      mPanel.ChildArranged +=
      	new CircularPanel.OnChildArranged(mPanel_ChildArranged);
  }
}

void mPanel_ChildArranged(object sender, UIElement child, double angle)
{
  MenuKillerItem childItem = child as MenuKillerItem;

  childItem.mPanel.AngleSpacing = Double.NaN;

  // These values should not be hardcoded, of course
  childItem.mPanel.StartAngle = angle - 45.0;
  childItem.mPanel.EndAngle = angle + 45.00;
}
</pre>
<h4>Opacity Issues</h4>
<p>Next, we want to dial down the opacity of the parent control&#8217;s button and all siblings to indicate which &#8216;path&#8217; is active in a visual manner. Unfortunately, there is an &#8216;opacity stack&#8217;, which makes it <a href="http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/">impossible to create a child element which is less transparent than its parent</a>. So we have to come up with a little helper method:</p>
<pre lang="csharp">
public void SetChildrenOpacity(UIElement exception, double dOpacity)
{
  foreach(UIElement elemRover in mPanel.Children)
  {
    if (elemRover != exception)
    {
      elemRover.Opacity = dOpacity;
    }
  }
}

void SetOpacityRecursively(int iLevel)
{
  // 2.0 seemed a little too much. One might want this to be configureable
  double dTargetOp = 1.0 / Math.Pow(1.4, iLevel);

  if (Parent is MenuKillerItem)
  {
    ((MenuKillerItem)Parent).SetChildrenOpacity(this, dTargetOp);
    ((MenuKillerItem)Parent).SetOpacityRecursively(++iLevel);
  }

  mCenterButton.Opacity = dTargetOp;
}
</pre>
<h3>The Tool Tip</h3>
<p>
We&#8217;re almost done!
</p>
<p>
There&#8217;s one thing left, however: The &#8216;tool tip&#8217; which is presented on the center button. This is meant to provide information about the button the mouse is currently over. So there are esentially two small problems to solve here: </p>
<ol>
<li>Identify the button that is under the mouse currently and retrieve its tooltip</li>
<li>Present the tool tip</li>
</ol>
<p>To find the item that is currently under the mouse, we have to get back to our template <code>PART_</code>s. We already registered a <code>MouseEnter</code> handler in the <code>MenuKillerItem</code> </p>
<pre lang="csharp">
void MenuKillerItem_MouseEnter(object o, MouseEventArgs e)
{
  Button sender = o as Button;

  if (null != sender)
  {
    sender.RaiseEvent(new RoutedEventArgs(MenuKillerItem.MouseHoverEvent, this));
  }
}
</pre>
<p>
The event raised in here is a custom one with a very bad (i.e. misleading, already existing) name:
</p>
<pre lang="csharp">
#region Attached Event MouseHover
public static readonly RoutedEvent MouseHoverEvent =
    EventManager.RegisterRoutedEvent("MouseHover",
                                    RoutingStrategy.Bubble,
                                    typeof(RoutedEventHandler),
                                    typeof(MenuKillerItem));

public static void AddMouseHoverHandler(DependencyObject o, RoutedEventHandler handler)
{
  ((UIElement)o).AddHandler(MenuKillerItem.MouseHoverEvent, handler);
}

public static void RemoveMouseHoverHandler(DependencyObject o, RoutedEventHandler handler)
{
  ((UIElement)o).RemoveHandler(MenuKillerItem.MouseHoverEvent, handler);
}
#endregion
</pre>
<p>
In order to make this available to the root <code>MenuKiller</code>, we have to have the <code>MenuKiller</code> catch the event as soon as it bubbles up and implement a <code>DependencyProperty</code> which makes the current &#8216;tool tip&#8217; available to the outside:
</p>
<pre lang="csharp">
void HandleMouseHover(object sender, RoutedEventArgs rea)
{
  if (null != rea)
  {
    MenuKillerItem mki = rea.OriginalSource as MenuKillerItem;

    if (null != mki)
    {
      HoverToolTip = mki.RootToolTip;
    }
  }
}
public static readonly DependencyProperty HoverToolTipProperty =
    DependencyProperty.Register(
        "HoverToolTip",
        typeof(object),
        typeof(MenuKiller),
        new PropertyMetadata(null));

public object HoverToolTip
{
  get
  {
    return (object)GetValue(HoverToolTipProperty);
  }
  set
  {
    SetValue(HoverToolTipProperty, value);
  }
}

public override void OnApplyTemplate()
{
  base.OnApplyTemplate();
  AddHandler(MenuKillerItem.MouseHoverEvent,
             new RoutedEventHandler(HandleMouseHover));
}
</pre>
<p>
As you can see, there is no template <code>PART_</code> that actually displays the tool tip. This is simply because I wanted to allow rich content within the tool tip (thus it is of type <code>object</code>) and I believe this to be a common modification. Requiring the control user to re-template the control just to change the appearance (or worse, the position) of the tool tip seems annoying.
</p>
<p>
Finally adding the tool tip in the actual &#8216;users&#8217; window markup is straightforward:
</p>
<pre lang="xaml">
<mk:ReferenceAlignPanel>
  <mk:MenuKiller  Margin="2,2,2,2"
                  x:Name="MKRoot"
                  HoverToolTip="Default Value">
      <!-- .... -->
  </mk:MenuKiller>
  <TextBox  Text="{Binding Path=HoverToolTip, ElementName=MKRoot, Mode=OneWay}"
            Width="128"
            HorizontalAlignment="Left"
            TextAlignment="Center"
            VerticalAlignment="Top"
            Height="20px"
            BorderThickness="0px"
            IsHitTestVisible="False"
            Background="Transparent"
            Margin="0, 192, 0,0"/>
</mk:ReferenceAlignPanel>
</pre>
<p>
As you can see, I chose a simple <code>TextBox</code>, although the system allows me to use images, too. The <code>Binding</code> to the <code>MenuKiller</code>&#8217;s <code>DependencyProperty HoverToolTip</code> does the job, the rest is merely a description of the desired appearance. The <code>Margin</code> makes the <code>TextBox</code> appear beneath the center.
</p>
<h2>Conclusion</h2>
<p>The MenuKiller Control offers a very different way of user interaction. With the introduction of WPF, the creation of this control has been simplified while keeping it customizeable at the same time. The use of databinding even allows to decouple parts of the control completely (e.g. tool tip box), thereby overcoming the issue of retemplating which usually requires to replace the whole template instead of replacing only specific parts.</p>
<p>The development of this control has taken a lof of iterations. For me, this was highly educating and a lot of fun. I hope to have contributed a little to a new discussion and new thinking in user interface design, while also providing a resource on how to develop custom WPF controls.</p>
<h2>Open Questions, Todos</h2>
<p>This control can certainly be optimized in various ways. There is still a lot of work to do to make this control really nice. For example, &#8216;adaptive arrange&#8217; is certainly necessary in some cases, furthermore, every modification to the arrangement could be animated for some eye candy. There is a lot to do terms of features and integration with <code>Popup</code>s, for example.</p>
<p>What matter most, though, is experience in using this control in a real world application. Customer and end-user feedback are required to help making this control what it is supposed to be one day: A fast, flexible, intuitive and context sensitive control with a small amount of text and happy end-user.</p>
<h2>Resources</h2>
<p>In the making&#8230;</p>
<h2>History</h2>
<ul>
<li>2008-05-04 v. 1.0 Initial release on emphess.net</li>
</ul>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=A+MenuKiller+Control+%E2%80%93+Draft+http://bit.ly/bW6Vcc" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/05/04/a-menukiller-control-draft/&amp;title=A+MenuKiller+Control+%E2%80%93+Draft" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/05/04/a-menukiller-control-draft/&amp;title=A+MenuKiller+Control+%E2%80%93+Draft" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/05/04/a-menukiller-control-draft/&amp;t=A+MenuKiller+Control+%E2%80%93+Draft" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/05/04/a-menukiller-control-draft/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Protected: A MenuKiller Sample Application</title>
		<link>http://www.emphess.net/2008/04/15/a-menukiller-sample-application/</link>
		<comments>http://www.emphess.net/2008/04/15/a-menukiller-sample-application/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 01:55:12 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[Differentiated UX]]></category>
		<category><![CDATA[MenuKiller]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=32</guid>
		<description><![CDATA[There is no excerpt because this is a protected post.]]></description>
			<content:encoded><![CDATA[<form action="http://www.emphess.net/wp-pass.php" method="post">
<p>This post is password protected. To view it please enter your password below:</p>
<p><label for="pwbox-32">Password:<br />
<input name="post_password" id="pwbox-32" type="password" size="20" /></label><br />
<input type="submit" name="Submit" value="Submit" /></p></form>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=Protected%3A+A+MenuKiller+Sample+Application+http://bit.ly/9dRGJK" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/15/a-menukiller-sample-application/&amp;title=Protected%3A+A+MenuKiller+Sample+Application" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/15/a-menukiller-sample-application/&amp;title=Protected%3A+A+MenuKiller+Sample+Application" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/15/a-menukiller-sample-application/&amp;t=Protected%3A+A+MenuKiller+Sample+Application" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/15/a-menukiller-sample-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ICommand.CanExecute() and NullReferenceException</title>
		<link>http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/</link>
		<comments>http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 17:12:57 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Custom Command]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[ICommand]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=31</guid>
		<description><![CDATA[Have you ever tried to call ICommand.CanExecute()? It actually works fine, but only if you are not as naive as I am&#8230; Simply calling it without the proper know-how might result in a NullReferenceException, so what you should read is how to implement ICommandSource. See
MSDN: How To: Implement ICommandSource
MSDN: Implement ICommandSource Sample.
Not a big thing, [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever tried to call <code>ICommand.CanExecute()</code>? It actually works fine, but only if you are not as naive as I am&#8230; Simply calling it without the proper know-how might result in a <code>NullReferenceException</code>, so what you should read is how to implement <code>ICommandSource</code>. See</p>
<p><a href="http://msdn2.microsoft.com/en-us/library/ms748978.aspx">MSDN: How To: Implement ICommandSource</a><br />
<a href="http://msdn2.microsoft.com/en-us/library/ms771361.aspx">MSDN: Implement ICommandSource Sample</a>.</p>
<p>Not a big thing, but since google didn&#8217;t show anything for &#8220;ICommand.CanExecute NullReferenceException&#8221;, it might help somebody I hope&#8230;</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=ICommand.CanExecute%28%29+and+NullReferenceException+http://bit.ly/d5NelM" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/&amp;title=ICommand.CanExecute%28%29+and+NullReferenceException" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/&amp;title=ICommand.CanExecute%28%29+and+NullReferenceException" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/&amp;t=ICommand.CanExecute%28%29+and+NullReferenceException" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/10/icommandcanexecute-and-nullreferenceexception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On UIElement.Opacity and the Removal of Storyboards</title>
		<link>http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/</link>
		<comments>http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 11:50:53 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=27</guid>
		<description><![CDATA[Today, I encountered two WPF related problems:
1 &#8211; UIElement.Opacity and the way it is being &#8216;inherited&#8217;
Every UIElement has an Opacity property, which will we be used when rendering the control. When rendering an object, 0.0 means the object is fully transparent, thereby invisible to the user, while 1.0 means it is fully opaque. Since controls [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I encountered two WPF related problems:</p>
<h4>1 &#8211; UIElement.Opacity and the way it is being &#8216;inherited&#8217;</h4>
<p>Every <code>UIElement</code> has an <code>Opacity</code> property, which will we be used when rendering the control. When rendering an object, <code>0.0</code> means the object is fully transparent, thereby invisible to the user, while <code>1.0</code> means it is fully opaque. Since controls can be composed so simply, it is desireable that child controls will use the opacity of their parents, so you don&#8217;t have to set it explicitly for each child.</p>
<p>So there is some kind of opacity stack, which will multiply opacities with each other when traversing down the tree upon rendering. Therefore, a 100% opaque button on a 10% opaque canvas will yield 10% opacity for the button (for an even longer description, see <a href="http://msdn2.microsoft.com/en-us/library/system.windows.uielement.opacity(VS.85).aspx">this MSDN entry</a>).</p>
<p>However, it also seemed natural to me that it is well possible to specify an opacity of 2.0, so the child of a half-transparent object is rendered fully opaque (the same math applies). This is, however, not the case. While there are no warnings or exceptions (even the value is preserved), it will be clipped during the rendering process silently, therefore not allowing any <code>UIElement</code> to be more opaque than their parent.</p>
<p>For the MenuKiller Control, that is a catastrophe, since it changes the opacity of children all the time in order to convey the hierarchical concept better.</p>
<p>So, what I came up with is a helper-method that does the whole thing manually&#8230; Any thoughts on this one?</p>
<p>I really don&#8217;t understand why this is not allowed, since it would make some things a lot easier, at a very low risk of objects that are too opaque.</p>
<h4>2 &#8211; The need to remove storyboards</h4>
<p>When testing the MenuKiller Control, I realized (not for the first time, but the first time it bugged me), that the XAML code I had did not work entirely correct.</p>
<p>The Button has a few triggers, including these:</p>
<pre class="brush: xml">
&lt;!-- exact storyboard omitted for clarity --&gt;
&lt;Trigger Property=&quot;IsMouseOver&quot; SourceName=&quot;contentPresenter&quot; Value=&quot;True&quot;&gt;
  &lt;Trigger.EnterActions&gt;
    &lt;BeginStoryboard x:Name=&quot;MouseOver_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource MouseOver}&quot;/&gt;
  &lt;/Trigger.EnterActions&gt;
  &lt;Trigger.ExitActions&gt;
    &lt;BeginStoryboard x:Name=&quot;MouseOut_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource MouseOut}&quot;/&gt;
  &lt;/Trigger.ExitActions&gt;
&lt;/Trigger&gt;
&lt;Trigger Property=&quot;IsPressed&quot;  Value=&quot;True&quot;&gt;
  &lt;Trigger.EnterActions&gt;
    &lt;BeginStoryboard x:Name=&quot;PressedOn_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource PressedOn}&quot;/&gt;
  &lt;/Trigger.EnterActions&gt;
  &lt;Trigger.ExitActions&gt;
    &lt;BeginStoryboard x:Name=&quot;PressedOff_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource PressedOff}&quot;/&gt;
  &lt;/Trigger.ExitActions&gt;
&lt;/Trigger&gt;
</pre>
<h4>Expected Behaviour</h4>
<p>The button has a trigger for the <code>IsMouseOver</code> property, so this should increase the opacity to 100% if hovering:<br />
<img src="http://www.emphess.net/wp-content/uploads/2008/04/mkbhover.png" alt="Screenshot of the desired hover effect." align="left" /></p>
<h4>Observed Behaviour</h4>
<p>This works, but only as long the button is never clicked. If the button is clicked once, it will simply stay at its default 0.7 opacity. The only thing that still works is the animation for <code>IsPressed</code>.</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/04/mkbhovererr.png" alt="Screenshot of non-hovering Button due to IsPressed Storyboard's ExitAction still pertaining." align="right" /><br />
(The red dot, by the way, is only a debugging tool, not a mistake)</p>
<p>I wondered how this could happen, trying to figure whether the button might behave like a <code>ToggleButton</code> for some reason. But it didn&#8217;t.</p>
<p>Instead, I realized that the trigger system, being based upon <code>EnterActions</code> and <code>ExitAction</code>s, would have to preserve the controls&#8217; state somehow. Several storyboards could easily cross each others paths, isn&#8217;t it? Interestingly, there is a property called <code>HandoffBehaviour</code> which I did not know until then. Unfortunately, the default value is already <code>SnapshotAndReplace</code>, while the only other option <code>Compose</code> was clearly not what I wanted.</p>
<p>As it turns out, the <code>ExitAction</code>, once applied, will stay on the control as long as the original enter condition is valid. Therefore, one simply has to remove the storyboard explicitly if another animation is supposed to be visible to the user. This yields the following XAML Code:</p>
<pre class="brush: xml">
&lt;Trigger Property=&quot;IsMouseOver&quot; SourceName=&quot;contentPresenter&quot; Value=&quot;True&quot;&gt;
  &lt;Trigger.EnterActions&gt;
    &lt;RemoveStoryboard BeginStoryboardName=&quot;PressedOff_BeginStoryboard&quot; /&gt;
    &lt;BeginStoryboard x:Name=&quot;MouseOver_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource MouseOver}&quot;/&gt;
  &lt;/Trigger.EnterActions&gt;
  &lt;Trigger.ExitActions&gt;
    &lt;RemoveStoryboard BeginStoryboardName=&quot;PressedOff_BeginStoryboard&quot; /&gt;
    &lt;BeginStoryboard x:Name=&quot;MouseOut_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource MouseOut}&quot;/&gt;
  &lt;/Trigger.ExitActions&gt;
&lt;/Trigger&gt;
&lt;Trigger Property=&quot;IsPressed&quot;  Value=&quot;True&quot;&gt;
  &lt;Trigger.EnterActions&gt;
    &lt;BeginStoryboard x:Name=&quot;PressedOn_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource PressedOn}&quot;/&gt;
  &lt;/Trigger.EnterActions&gt;
  &lt;Trigger.ExitActions&gt;
    &lt;BeginStoryboard x:Name=&quot;PressedOff_BeginStoryboard&quot;
                     Storyboard=&quot;{StaticResource PressedOff}&quot;/&gt;
  &lt;/Trigger.ExitActions&gt;
&lt;/Trigger&gt;
</pre>
<p>What it accomplished, in the end, is the newest incarnation of the MenuKiller, here in Debug draw-mode:</p>
<p><img src="http://www.emphess.net/wp-content/uploads/2008/04/mkdebug.png" alt="Screenshot of the MenuKiller Control in a debug version." align="center" /></p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=On+UIElement.Opacity+and+the+Removal+of+Storyboards+http://bit.ly/awvqr8" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/&amp;title=On+UIElement.Opacity+and+the+Removal+of+Storyboards" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/&amp;title=On+UIElement.Opacity+and+the+Removal+of+Storyboards" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/&amp;t=On+UIElement.Opacity+and+the+Removal+of+Storyboards" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/10/on-uielementopacity-and-the-removal-of-storyboards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Applying ItemContainerStyle Recursively</title>
		<link>http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/</link>
		<comments>http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 18:23:20 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[TreeView]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=25</guid>
		<description><![CDATA[In the MenuKiller Control, I need to configure a TreeView to quite some extent: I want all nodes to have a certain custom ItemContainerStyle. 
First naive approach: The TreeView will apply its ItemContainerStyle to all nodes. Wrong! The TreeViewItems themselves are ItemControls, therefore having their own ItemContainerStyle.
Second approach: Have the ItemContainerStyle refer to itself using [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/">MenuKiller Control</a>, I need to configure a <code>TreeView</code> to quite some extent: I want all nodes to have a certain custom <code>ItemContainerStyle</code>. </p>
<p>First naive approach: The <code>TreeView</code> will apply its <code>ItemContainerStyle</code> to all nodes. <b>Wrong!</b> The <code>TreeViewItem</code>s themselves are <code>ItemControl</code>s, therefore having their own <code>ItemContainerStyle</code>.</p>
<p>Second approach: Have the <code>ItemContainerStyle</code> refer to itself using a <code>DynamicResource</code>:</p>
<div>
<pre class="brush: xml">
&lt;Style x:Key=&quot;MKItemStyle&quot; TargetType=&quot;{x:Type local:MenuKillerItem}&quot;&gt;
    &lt;Setter Property=&quot;Template&quot; Value=&quot;{StaticResource MenuKillerItemTemplate}&quot;/&gt;
    &lt;Setter Property=&quot;ItemContainerStyle&quot; Value=&quot;{DynamicResource MKItemStyle}&quot;/&gt;
&lt;/Style&gt;
</pre>
</div>
<p><b>Wrong again!</b> This does not work. Frankly, I don&#8217;t know why, but I didn&#8217;t bother to debug it. </p>
<p>There are quite some articles on customizing <code>TreeView</code>s the net, for example Josh Smith&#8217;s article <a href="http://www.codeproject.com/KB/WPF/CustomTreeViewLayout.aspx">&#8220;Custom TreeView Layout in WPF&#8221;</a> at the CodeProject. There didn&#8217;t seem to be any such problem&#8230; So what&#8217;s the catch?</p>
<h4>A Simple Solution?</h4>
<p>So what is it all about? In the source code accompanying Josh&#8217;s article, we find the following declaration:</p>
<pre class="brush: xml">
&lt;!-- This Style redefines the ControlTemplate used by TreeViewItems and
       also provides a different itemspanel for their child items. --&gt;
&lt;Style TargetType=&quot;TreeViewItem&quot;&gt;
  [...]
&lt;/Style&gt;
</pre>
<p>So this will simply apply the defined style to each and every item of the TargetType.<br />
<b>Done!</b>.</p>
<p>There are some drawbacks, though: In a small application, this might be OK, but it may result in problems with larger applications or control libraries. One simple trick, of course, is to create a custom control which derives from the control you want, and apply a default style to this derived type (I currently do this for the <code>MenuKillerItem</code>, which derives from <code>TreeViewItem</code>).</p>
<p>Yet, this solution is not well-templateable either. Users of a control library might want to override the default template only for children of a specific control, which is not possible this way.</p>
<p>Of course, one can write a recursive method to apply the style, but I doubt this is the cleanest solution. Any better ideas?</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=Applying+ItemContainerStyle+Recursively+http://bit.ly/cBCIpk" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/&amp;title=Applying+ItemContainerStyle+Recursively" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/&amp;title=Applying+ItemContainerStyle+Recursively" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/&amp;t=Applying+ItemContainerStyle+Recursively" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/07/applying-itemcontainerstyle-recursively/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The MenuKiller Control &#8211; Differentiated UX</title>
		<link>http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/</link>
		<comments>http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 17:00:50 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[Differentiated UX]]></category>
		<category><![CDATA[DUX]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=20</guid>
		<description><![CDATA[
A while ago, I read a very interesting blog post: Rethinking the Button by Dax Pandhi. It really fascianated me, so I started some research on the topic. Apparently, &#8220;Differentiated UX&#8221; is the new buzzword. As is always the case with buzzwords, different people understand it in different way, but I guess the common denominator is: We [...]]]></description>
			<content:encoded><![CDATA[<p>
A while ago, I read a very interesting blog post: <a title="Dax Pandhi - Rethinking the Button" href="http://blog.nukeation.com/post/UX-Concepts---Rethinking-the-Button.aspx" target="_blank">Rethinking the Button </a>by Dax Pandhi. It really fascianated me, so I started some research on the topic. Apparently, &#8220;Differentiated UX&#8221; is <em>the</em> new buzzword. As is always the case with buzzwords, different people understand it in different way, but I guess the common denominator is: We haven&#8217;t been putting enough effort into User Interfaces, because we simply stuck to what was there (at least, most of us). </p>
<p>
<img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://www.emphess.net/wp-content/uploads/2008/04/mk2.png" alt="MenuKiller screen shot" align="left" />
</p>
<p>
With WPF, things have changed quite a bit. What makes a control? In Windows Forms, a control had a certain look and behaviour. Some of it could be modified (e.g. the colors, the way the button behaves on click, etc.), yet a lot of it was fixed. For example, many controls had a <code>Text</code>-Property which accepted a string of course.<br />
WPF Controls, on the other hand, have Content or Items, which can again be controls. So you can finally put an image into a tooltip with a few lines of purely declarative XAML code. Therefore, in WPF, a control is far less specific. Many scenarios that demanded a custom control in Windows Forms are now merely a different content, or a template.
</p>
<p>
Anyway, I wanted to use Dax&#8217;s control I a project of mine, but even though his <a href="http://www.nukeation.net/2007/10/29/Simple+ImageButton+ControlTemplate.aspx">original code</a> was sufficient to build a simple demo of the control, I wanted to create a nice templateable custom control with all the behaviour we need. As it turns out, doing that is not trivial, especially for a WPF Newbie like me.
</p>
<p>
The learning curve was really steep, but I really learned a lot about WPF, custom controls and control authoring this way. The delay I&#8217;m having is really huge, so this is really a post about an upcoming article. However, since the control is now almost finished, here are some screenshots and the xaml code that the user will need to create the control:
</p>
<p>
<img src="http://www.emphess.net/wp-content/uploads/2008/04/mk1.jpg" alt="MenuKiller screen shot" align="right" /></p>
<pre class="brush: xml">
&lt;mk:MenuKiller VerticalAlignment=&quot;Center&quot;&gt;
  &lt;mk:MenuKillerItem&gt;
    &lt;mk:MenuKillerItem.Header&gt;
      &lt;Image Width=&quot;64&quot; Source=&quot;....png&quot;/&gt;
    &lt;/mk:MenuKillerItem.Header&gt;

    &lt;mk:MenuKillerItem&gt;
      &lt;mk:MenuKillerItem.Header&gt;
        &lt;Image Width=&quot;32&quot; Source=&quot;....png&quot;/&gt;
      &lt;/mk:MenuKillerItem.Header&gt;
    &lt;/mk:MenuKillerItem&gt;

    &lt;mk:MenuKillerItem&gt;
      &lt;mk:MenuKillerItem.Header&gt;
        &lt;Image Width=&quot;32&quot; Source=&quot;....png&quot;/&gt;
      &lt;/mk:MenuKillerItem.Header&gt;
    &lt;/mk:MenuKillerItem&gt;

    &lt;mk:MenuKillerItem&gt;
      &lt;mk:MenuKillerItem.Header&gt;
        &lt;Image Width=&quot;32&quot; Source=&quot;....png&quot;/&gt;
      &lt;/mk:MenuKillerItem.Header&gt;
    &lt;/mk:MenuKillerItem&gt;

    &lt;mk:MenuKillerItem&gt;
      &lt;mk:MenuKillerItem.Header&gt;
        &lt;Image Width=&quot;32&quot; Source=&quot;....png&quot;/&gt;
      &lt;/mk:MenuKillerItem.Header&gt;
    &lt;/mk:MenuKillerItem&gt;
  &lt;/mk:MenuKillerItem&gt;
&lt;/mk:MenuKiller&gt;
</pre>
<p>
As you can see, using the control is really simple. The cool icons, by the way, are from <a href="http://wearwolfaa.deviantart.com/art/23-PNG-Vista-Style-Icons-74510840">http://wearwolfaa.deviantart.com/art/23-PNG-Vista-Style-Icons-74510840</a>.
</p>
<p>
Stay tuned &#8211; I will be busy on The CodeProject the next days, where I will certainly write an article about this control!
</p>
<p>
My current solution involves a custom panel, an overridden tree-view and tree view item, a rather complex default-theme, Custom Commands, 2 &#8220;PART_&#8221;-Controls within the template that can be overridden as well as a set of custom converters. This is not final, however, because some of these items currently don&#8217;t do a thin.
</p>
<p>
Still, everything is a little simplified, since I wanted to support the probable and important cases first, rather than the offbeat scenario. 
</p>
<p>
I also had a very long and important customer meeting yesterday where I presented this control in a demo app. Now people generally try to stick to what they know, but while my customer argued that the &#8216;old way&#8217; should still be available to end-users, he also showed a lot of interest in this new kind of user experience.
</p>
<p>
If you want to read about Differentiated UX further, I suggest these resources:
</p>
<p>
Sample Applications: <a href="http://www.vertigo.com/familyshow.aspx">Familiy.Show</a>, <a href="http://wpf.netfx3.com/files/folders/applications/entry7625.aspx">Woodgrove Finance Application</a> and <a href="http://www.thirteen23.com/work/cine.view/">Cine.View</a>.
</p>
<p>
Posts and Articles: <a title="Dax Pandhi - Differentiated UX" href="http://blog.nukeation.com/post/Differentiated-UX.aspx" target="_blank">Differentiated UX</a> by Dax Pandhi, <a title="Brian Noyes - Differentiated UX" href="http://www.softinsight.com/bnoyes/PermaLink.aspx?guid=0158f4a8-1b7f-4bd0-aed5-5cf5a65389c2" target="_blank">Differentiated UX</a> by Brian Noyes
</p>
<p>
My dearest thanks to Dax, who has encouraged me to build this control and has always been a valuable brainstorm victim <img src='http://www.emphess.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Cheers Dax!
</p>
<p>
Chris</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=The+MenuKiller+Control+%E2%80%93+Differentiated+UX+http://bit.ly/ckHEdw" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/&amp;title=The+MenuKiller+Control+%E2%80%93+Differentiated+UX" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/&amp;title=The+MenuKiller+Control+%E2%80%93+Differentiated+UX" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/&amp;t=The+MenuKiller+Control+%E2%80%93+Differentiated+UX" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/07/the-menukiller-control-differentiated-ux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom DependencyProperties and &#8220;Auto&#8221;</title>
		<link>http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/</link>
		<comments>http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 10:28:40 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[Dependency Property]]></category>
		<category><![CDATA[TypeConverter]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/?p=17</guid>
		<description><![CDATA[While implementing a little custom control (a radial panel, actually &#8211; stay tuned what it&#8217;s good for&#8230;), I stumbled across a little problem when trying to add automatic behaviour.
Many built-in WPF Controls such as Canvas or Panel allow something like

Width=&#34;Auto&#34;

Now, for my control I need something that accepts

AngleSpacing=&#34;Auto&#34;
AngleSpacing=&#34;&#60;double&#62;&#34;

Of course, accomplishing that is very simple, but [...]]]></description>
			<content:encoded><![CDATA[<p>While implementing a little custom control (a radial panel, actually &#8211; stay tuned what it&#8217;s good for&#8230;), I stumbled across a little problem when trying to add automatic behaviour.</p>
<p>Many built-in WPF Controls such as <code>Canvas</code> or <code>Panel</code> allow something like</p>
<pre class="brush: csharp">
Width=&quot;Auto&quot;
</pre>
<p>Now, for my control I need something that accepts</p>
<pre class="brush: csharp">
AngleSpacing=&quot;Auto&quot;
AngleSpacing=&quot;&lt;double&gt;&quot;
</pre>
<p>Of course, accomplishing that is very simple, but it took me some time to find it <a title="MSDN on FrameworkElement.Height" href="http://msdn2.microsoft.com/en-us/library/system.windows.frameworkelement.height.aspx" target="_blank">on MSDN:</a></p>
<blockquote><p>In addition to acceptable <a id="ctl00_rs1_mainContentContainer_ctl69" href="http://msdn2.microsoft.com/en-us/library/system.double.aspx">Double</a> values, this property can also be <a id="ctl00_rs1_mainContentContainer_ctl70" href="http://msdn2.microsoft.com/en-us/library/system.double.nan.aspx">Double<span class="cs">.</span>NaN</a>. This is how you specify auto sizing behavior in code. In XAML you set the value to the string &#8220;Auto&#8221; (case insensitive) to enable the auto sizing behavior. Auto sizing behavior implies that the element will fill the height available to it. Note however that specific controls frequently supply default values through their default theme styles that will disable the auto sizing behavior unless it is specifically re-enabled.</p></blockquote>
<p>So, the solution simply is to apply the <code>TypeConverterAttribute</code> as follows:</p>
<pre class="brush: csharp">
[TypeConverterAttribute(typeof(LengthConverter))]
public double AngleSpacing
{
    get { return (double)GetValue(AngleSpacingProperty); }
    set { SetValue(AngleSpacingProperty, value); }
}
public static readonly DependencyProperty AngleSpacingProperty =
    DependencyProperty.Register(&quot;AngleSpacing&quot;,
                                  typeof(double),
                                  typeof(CircularPanel),
                                  new FrameworkPropertyMetadata(45d,
                                  FrameworkPropertyMetadataOptions.AffectsArrange));
</pre>
<p>This will, however, leave us with a length converter (which is built mainly for Conversion of &#8220;pt&#8221;, &#8220;px&#8221;, etc.). There are quite a lot of type coverters available already. For a list, see <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx">http://msdn2.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx</a>.  </p>
<p>In my case, I need a custom <code>TypeConverter</code>, which is really simple:</p>
<pre class="brush: csharp">
public class DoubleAutoConverter : TypeConverter
{
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    if (sourceType == typeof(string) || sourceType == typeof(double))
    {
      return true;
    }

    return base.CanConvertFrom(context, sourceType);
  }

  // Overrides the ConvertFrom method of TypeConverter.
  public override object ConvertFrom(ITypeDescriptorContext context,
     CultureInfo culture, object value)
  {
    if (value is string)
    {
      double dValue;

      if (String.Compare((string)value, &quot;auto&quot;, true) == 0)
      {
        dValue = Double.NaN;
      }
      else
      {
        // Don&#039;t catch the exception
        dValue = Double.Parse((string)value);
      }

      return dValue;
    }

    // No need to handle the trivial case manually:
    return base.ConvertFrom(context, culture, value);
  }

  public override object ConvertTo(ITypeDescriptorContext context,
     CultureInfo culture, object value, Type destinationType)
  {
    return base.ConvertTo(context, culture, value, destinationType);
  }
}
</pre>
<p>Now, when the user specifies auto, the property will be set to <code>Double.NaN</code> and can be handled by the control&#8230; hopefully</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=Custom+DependencyProperties+and+%E2%80%9CAuto%E2%80%9D+http://bit.ly/b7zCxv" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/&amp;title=Custom+DependencyProperties+and+%E2%80%9CAuto%E2%80%9D" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/&amp;title=Custom+DependencyProperties+and+%E2%80%9CAuto%E2%80%9D" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/&amp;t=Custom+DependencyProperties+and+%E2%80%9CAuto%E2%80%9D" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/04/02/custom-dependencyproperties-and-auto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tao Framework now DPI Aware!</title>
		<link>http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/</link>
		<comments>http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 16:12:45 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[DPI Awareness]]></category>
		<category><![CDATA[Tao]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/</guid>
		<description><![CDATA[Huge thanks to Ilmar Kruis for implementing GetDeviceCaps() in the Tao framework! With some small modifications I suggested, one can now easily develop DPI-aware OpenGL applications using C# or .NET in general! Thanks Ilmar!
I will update my article on the CodeProject about OpenGL windows in Vista soon!
See http://www.taoframework.com/
Get the latest version via SVN: https://taoframework.svn.sourceforge.net/svnroot/taoframework 
 [...]]]></description>
			<content:encoded><![CDATA[<p>Huge thanks to Ilmar Kruis for implementing GetDeviceCaps() in the Tao framework! With some small modifications I suggested, one can now easily develop DPI-aware OpenGL applications using C# or .NET in general! Thanks Ilmar!</p>
<p>I will update my article on the CodeProject about OpenGL windows in Vista soon!</p>
<p>See <a href="http://www.taoframework.com/">http://www.taoframework.com/</a></p>
<p>Get the latest version via SVN: <font face="Courier New">https://taoframework.svn.sourceforge.net/svnroot/taoframework </font></p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=Tao+Framework+now+DPI+Aware%21+http://bit.ly/djjknW" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/&amp;title=Tao+Framework+now+DPI+Aware%21" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/&amp;title=Tao+Framework+now+DPI+Aware%21" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/&amp;t=Tao+Framework+now+DPI+Aware%21" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/03/28/tao-framework-now-dpi-aware/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating OpenGL Windows in WPF</title>
		<link>http://www.emphess.net/2008/02/19/hello-world-2/</link>
		<comments>http://www.emphess.net/2008/02/19/hello-world-2/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 18:36:11 +0000</pubDate>
		<dc:creator>Christoph Menge</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[HelloWorld]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.oblivion-legion.de/emphess.net/?p=3</guid>
		<description><![CDATA[Hello, World!
Ok, my first blog entry! I also posted my first article at The CodeProject today:
Creating OpenGL Windows in WPF
Have fun!
   ]]></description>
			<content:encoded><![CDATA[<p>Hello, World!</p>
<p>Ok, my first blog entry! I also posted my first article at The CodeProject today:</p>
<p><a href="http://www.codeproject.com/KB/WPF/WPFOpenGL.aspx">Creating OpenGL Windows in WPF</a></p>
<p>Have fun!</p>
<div style="float: right;"><p align="right"><a rel="nofollow" class="tt" href="http://twitter.com/home/?status=Creating+OpenGL+Windows+in+WPF+http://bit.ly/bXzSyN" title="Post to Twitter"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a rel="nofollow" class="tt" href="http://delicious.com/post?url=http://www.emphess.net/2008/02/19/hello-world-2/&amp;title=Creating+OpenGL+Windows+in+WPF" title="Post to Delicious"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a rel="nofollow" class="tt" href="http://digg.com/submit?url=http://www.emphess.net/2008/02/19/hello-world-2/&amp;title=Creating+OpenGL+Windows+in+WPF" title="Post to Digg"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a rel="nofollow" class="tt" href="http://www.facebook.com/share.php?u=http://www.emphess.net/2008/02/19/hello-world-2/&amp;t=Creating+OpenGL+Windows+in+WPF" title="Post to Facebook"><img class="nothumb" src="http://www.emphess.net/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.emphess.net/2008/02/19/hello-world-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
