Preserving Whitespaces Between XAML Tags

| 0 comments

Filipe Fortes just blogs about Collapsed Spaces Around <Run /> issue in WPF, and his workaround is placing the text containing white spaces into the Text attribute, actually this is not a nice way of doing this, and you can actually twick the XAML parser to respect white spaces between XAML tags using the following trick:

<Pagexmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<
TextBlock>
<
Run xml:space="preserve">Hello XAML !</Run>
</
TextBlock>
</
Page>


For complete explanation on xml:space, you can refer to msdn documentation on Whitespace Processing in XAML.

Some Rambles On Singleton Pattern

| 0 comments

Singleton design pattern is a widely discussed topic among the blogspere, and there are many good articles dedicated to this massively applied design pattern, such as Implementing the Singleton Pattern in C# and The "Double-Checked Locking is Broken" Declaration. Just recently, I came across a relatively old blog article by Brad Abrams talking about how to make double checked locking Singleton pattern work properly in C#. With all those splendid reading as backbone, I add another two ways of implementing double checked locking pattern.

My first approach is mutated from the memory barrier trick Brad talked about in his blog article:

public sealed class Singleton
{
    private static Object syncRoot = new Object();
    private static Object instance;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            Singleton temp = null;
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        temp = new Singleton();

                        //Fully publish the Singleton object in memory to make it visible to all processors.
                        System.Threading.Thread.VolatileWrite(ref instance, temp);
                    }
                }
            }
            return temp;
        }
    }
}

Since Thread.VolatileWrite() method will do exactly what Thread.MemoryBarrier() does, so this approach is nothing different from Brad's.

Another approach to properly implement double checked locking is using TLS (Thread Local Storage) as The "Double-Checked Locking is Broken" Declaration article demonstrates. The original implementation is using Java, when implementing this approach in C#, you can get additional benefit out of ThreadStaticAttribute:

public sealed class Singleton
{
    [ThreadStatic]
    private static Int32 syncFlag = 0;
    private static Object syncRoot = new Object();
    private static Singleton instance;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (syncFlag == 0) // Is the current thread online?
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }

                syncFlag = 1; // Indicate the current thread is online
            }
            return instance;
        }
    }
}  


Although, theoretically speaking, the two implementations shown above "should" work as expected, but without heavy testing on different hardware configurations, no one can make this guarantee:)

Application.DoEvents In WPF Revisited

| 0 comments

A long time ago, I blogged about how to implement the Application.DoEvents logic in WPF, Windows Forms has this method for the very beginning, but WPF doesn't build this logic into the framework, I think WPF team made a good decision here, because as I've mentioned in my original blog article, nested message pump is evil. But at some rare circumstances, DoEvents can solve some of the problems such as how to expand TreeViewItems as I've blogged ages ago.

Recently, I just find another way to implement the DoEvents method, and this version of DoEvents only requires a single line of code:

using System;
using System.Threading;
using System.Windows;
using System.Windows.Threading;

namespace Sheva.Windows
{
    /// <summary>
    /// Designates a Windows Presentation Foundation application with added functionalities.
    /// </summary>
    public class WpfApplication : Application
    {
        /// <summary>
        /// Processes all messages currently in the message queue.
        /// </summary>
        /// <remarks>
        /// This method can potentially cause code re-entrancy problem, so use it with great care.
        /// </remarks>
        public static void DoEvents()
        {
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
        }
    }
}

Actually, Dispatcher.Invoke will do proper nested pumping for you when the priority is anything than DispatcherPriority.Send.

Virtual Method Performance

| 0 comments

Bart J.F. De Smet just blogs about the performance discrepancy when calling vitual methods and non-virtual methods, in his original testing code, he just compares calling virual methods and non-virtual methods through class-based references, actually calling virtual methods through interface-based references will also incur additional performance overhead, I modify his original code to include the testing snippet for calling virtual methods through interface-based reference:

using System;
using System.Diagnostics;

interface IFoo
{
    void Do();
}

class Virt : IFoo
{
    public virtual void Do() { }
    public void DoIt() { }

    static void Main()
    {
        Virt v = new Virt();

        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000000000; i++)
            v.DoIt();
        sw.Stop();
        Console.WriteLine("Calling non-virtual method:{0}", sw.Elapsed);

        sw.Reset();
        sw.Start();
        for (int i = 0; i < 1000000000; i++)
            v.Do();
        sw.Stop();
        Console.WriteLine("Calling virtual method using class-based reference:{0}", sw.Elapsed);

        sw.Reset();
        sw.Start();
        IFoo f = v as IFoo;
        for (int i = 0; i < 1000000000; i++)
            f.Do();
        sw.Stop();
        Console.WriteLine("Calling virtual method using interface-based reference:{0}", sw.Elapsed);
    }
}
 

When compiling the above code using "csc /o /target:exe test.cs", and running it, I get the following output from the console:

Calling non-virtual method:00:00:01.6662637
Calling virtual method using class-based reference:00:00:03.9324559
Calling virtual method using interface-based reference:00:00:05.6118531

And when examining the compiled MSIL code using ildasme.exe, the callvirt opcode is used in the three testing snippets:

IL_0017: callvirt instance void Virt::DoIt() //v.DoIt()

IL_0054: callvirt instance void Virt::Do() //v.Do()

IL_0096: callvirt instance void IFoo::Do() //f.Do()

You can see that the three callvirt calls will result in three different performance results, I don't plan to explain why it works this way, because all I know about virtual method dispatching in CLR is learnt from Don Box's Essential .NET: Common Language Runtime, this book give a complete treatment on virtual methods and how it works.

Visual Level Programming vs Logical Level Programming

| 0 comments

Josh Smith recently posts a great article on codeproject on how to write a custom control to enable spell checking suggestions in WPF, and his article is well written and pretty concise indeed, but he's got a problem when doing adorner layer programming, as he asked in this MSDN forum post. Since I also got the similar problem. So I digged in and with the great help of Ian Griffiths, I got the problem sorted out.  

The problem both Josh and I encounter is something to do with DP value inheritance on those visuals drawn in the adorner layer using visual layer programming technique, first off I don't agree with Josh's comments about the visual tree and adorner layer. Actually those visuals drawn in the adorner layer are also part of the visual tree if you programme it in the proper way, the reason the inherited DP values are "invisible" to the adorning visuals should be something to do with how we add those visuals in the adorner layer as Ian Griffiths suggests. The following code is a simplified version of the custom Adorner which can host a single UIElement properly:

public class UIElementAdorner : Adorner
{
    private UIElement child;
    public UIElementAdorner(UIElement element, UIElement adornedElement)
        : base(adornedElement)
    {
        this.child = element;
        base.AddLogicalChild(element);
        base.AddVisualChild(element);
    }

    protected override Size MeasureOverride(Size constraint)
    {
        this.child.Measure(constraint);
        return child.DesiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        this.child.Arrange(new Rect(finalSize));
        return finalSize;
    }

    protected override Int32 VisualChildrenCount
    {
        get { return 1; }
    }

    protected override Visual GetVisualChild(Int32 index)
    {
        return this.child;
    }

    protected override IEnumerator LogicalChildren
    {
        get
        {
            ArrayList list = new ArrayList();
            list.Add(this.child);
            return (IEnumerator)list.GetEnumerator();
        }
    }
}

The above code demonstrates both on how to define visual tree using visual layer programming and how to define the logical tree. When defining the visual tree, you should override GetVisualChild method and VisualChildrenCount property to enable proper indexing on the hosted visuals, optionally you can make the call to Visual.AddVisualChild method to establish the child-parent relationship for the visual tree of the custom element. this call is mandatory if you are hosting single visual, and you want to enable dependency property inheritance and UI interaction on this visual. If you are hosting multiple visuals, you can use the VisualCollection to establish the children-parent relationship. When defining the logical tree, you should override the LogicalChilden property, and if you are adding single element, you should call the FrameworkElement.AddLogicalChild method, and  if you are adding multiple elements, you can use UIElementCollection to store the logical children.

So If we use UIElementCollection, the above code can be re-written as follows:

public class UIElementAdorner : Adorner
{
    private UIElementCollection children;
    public UIElementAdorner(UIElement element, UIElement adornedElement) : base(adornedElement)
    {
        children = new UIElementCollection(this, this);
        children.Add(element);
    }

    protected override Size MeasureOverride(Size constraint)
    {
        this.children[0].Measure(constraint);
        return this.children[0].DesiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        this.children[0].Arrange(new Rect(finalSize));
        return finalSize;
    }

    protected override Int32 VisualChildrenCount
    {
        get { return 1; }
    }

    protected override Visual GetVisualChild(Int32 index)
    {
        return this.children[0];
    }

    protected override IEnumerator LogicalChildren
    {
        get
        {
            return (IEnumerator)children.GetEnumerator();
        }
    }
}

If you use VisualCollection instead, the code can be mutated like this:

public class UIElementAdorner : Adorner
{
    private UIElement child;
    private VisualCollection visuals;
    public UIElementAdorner(UIElement element, UIElement adornedElement)
        : base(adornedElement)
    {
        visuals = new VisualCollection(this);
        this.child = element;
        visuals.Add(element);
        base.AddLogicalChild(element);
        //base.AddVisualChild(element);
    }

    protected override Size MeasureOverride(Size constraint)
    {
        this.child.Measure(constraint);
        return child.DesiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        this.child.Arrange(new Rect(finalSize));
        return finalSize;
    }

    protected override Int32 VisualChildrenCount
    {
        get { return 1; }
    }

    protected override Visual GetVisualChild(Int32 index)
    {
        return this.child;
    }

    protected override IEnumerator LogicalChildren
    {
        get
        {
            ArrayList list = new ArrayList();
            list.Add(this.child);
            return (IEnumerator)list.GetEnumerator();
        }
    }
}

As the final words, since UIElementCollection enables both visual tree level and logical tree level programming, It's more appropriate when defining new content model for you cutsom control, because ContentControl, ItemsControl, HeaderedContentControl, and HeaderedItemsControl all don't fit into your peculiar need. But if you want to programme at the visual level to gain better performance, VisualCollection is more appropriate. And also note that if you just hosing single element, VisualCollection and UIElementCollection all seem a bit overkilled, just mind you, a collection object which contains a single object takes much more memory than the single object itself, so when hosting single element, the first code sample makes more sense.

Last but not least, my greatest thanks is given to Ian Griffiths for his wonderful tips on Visual.AddVisualChild method and overriding LogicalChildren property.

How To Host Top-Level HWNDs In WPF

| 2 comments

Someone asks in MSDN forum on how to host top-level form in WPF, To be pedantic, the System.Windows.Window in WPF is "big" top-level hwnd indeed, and you cannot put another top-level hwnd into this hwnd, this is not a WPF limitation, this is actually a limitation imposed by Win32, but Win32 does allow you to add child hwnds, you can work around this limitation by "transforming" the top-level hwnd into a child hwnd, I've created a custom control which can do this trick:

using System;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Forms.Integration;
using System.Runtime.InteropServices;

namespace Sheva.Windows.Interop
{
    [System.Windows.Markup.ContentProperty("Child")]
    public class FormHost : HwndHost
    {
        private System.Windows.Forms.Form child;

        public event EventHandler<ChildChangedEventArgs> ChildChanged;

        public System.Windows.Forms.Form Child
        {
            get { return child; }
            set
            {
                HwndSource ps = PresentationSource.FromVisual(this) as HwndSource;
                if (ps != null && ps.Handle != IntPtr.Zero)
                    throw new InvalidOperationException("Cannot set the Child property after the layout is done.");
                System.Windows.Forms.Form oldChild = child;
                child = value;
                OnChildChanged(oldChild);
            }
        }

        public Boolean ShowCaption
        {
            get
            {
                CheckChildValidity();
                return (GetWindowStyle(Child.Handle) & WindowStyles.WS_BORDER) == WindowStyles.WS_CAPTION;
            }
            set
            {
                if (child == null)
                {
                    this.ChildChanged += delegate
                    {
                        if (value)
                        {
                            SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) | WindowStyles.WS_CAPTION);
                        }
                        else
                        {
                            SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) & ~WindowStyles.WS_CAPTION);
                        }
                    };
                }
                else
                {
                    if (value)
                    {
                        SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) | WindowStyles.WS_CAPTION);
                    }
                    else
                    {
                        SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) & ~WindowStyles.WS_CAPTION);
                    }
                }
            }
        }

        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            CheckChildValidity();
            HandleRef childHwnd = new HandleRef(Child, child.Handle);
            SetWindowStyle(childHwnd.Handle, WindowStyles.WS_CHILD | GetWindowStyle(childHwnd.Handle));
            WindowsFormsHost.EnableWindowsFormsInterop();
            System.Windows.Forms.Application.EnableVisualStyles();
            SetParent(childHwnd.Handle, hwndParent.Handle);
            return childHwnd;
        }

        protected override void DestroyWindowCore(HandleRef hwnd)
        {
            child.Dispose();
        }

        protected void OnChildChanged(System.Windows.Forms.Form oldChild)
        {
            if (this.ChildChanged != null)
            {
                this.ChildChanged(this, new ChildChangedEventArgs(oldChild));
            }
        }

        private void CheckChildValidity()
        {
            if (child == null || child.Handle == IntPtr.Zero)
            {
                throw new ArgumentNullException("child form cannot be null");
            }
        }

        public static readonly Int32 GWL_STYLE = -16;
        public static readonly UInt32 WS_CHILD = 0x40000000;

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);
        [DllImport("user32.dll")]
        internal static extern WindowStyles GetWindowLong(IntPtr hWnd, Int32 nIndex);
        [DllImport("user32.dll")]
        internal static extern UInt32 SetWindowLong(IntPtr hWnd, Int32 nIndex, UInt32 dwNewLong);

        internal WindowStyles GetWindowStyle(IntPtr hWnd)
        {
            return (WindowStyles)GetWindowLong(hWnd, GWL_STYLE);
        }

        internal void SetWindowStyle(IntPtr hWnd, WindowStyles windowStyle)
        {
            SetWindowLong(hWnd, GWL_STYLE, (UInt32)windowStyle);
        }
    }

    [Flags]
    internal enum WindowStyles : uint
    {
        WS_OVERLAPPED = 0x00000000,
        WS_POPUP = 0x80000000,
        WS_CHILD = 0x40000000,
        WS_MINIMIZE = 0x20000000,
        WS_VISIBLE = 0x10000000,
        WS_DISABLED = 0x08000000,
        WS_CLIPSIBLINGS = 0x04000000,
        WS_CLIPCHILDREN = 0x02000000,
        WS_MAXIMIZE = 0x01000000,
        WS_BORDER = 0x00800000,
        WS_DLGFRAME = 0x00400000,
        WS_VSCROLL = 0x00200000,
        WS_HSCROLL = 0x00100000,
        WS_SYSMENU = 0x00080000,
        WS_THICKFRAME = 0x00040000,
        WS_GROUP = 0x00020000,
        WS_TABSTOP = 0x00010000,

        WS_MINIMIZEBOX = 0x00020000,
        WS_MAXIMIZEBOX = 0x00010000,

        WS_CAPTION = WS_BORDER | WS_DLGFRAME,
        WS_TILED = WS_OVERLAPPED,
        WS_ICONIC = WS_MINIMIZE,
        WS_SIZEBOX = WS_THICKFRAME,
        WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,

        WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
        WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
        WS_CHILDWINDOW = WS_CHILD,
    }
}


The above code also demonstrates how to make custom HwndHost in WPF, note that in the setter of Child property, I've checked to see if the layout is already done, this is important because BuildWindowCore method will be called during the layout pass, and it's meaningless to set the Child property after BuildWindowCore is made. and also note that I make a call to WindowsFormsHost.EnableWindowsFormsInterop() method, this is also pretty important if you want the hosted Form object to properly get notified with the keyboard related messages, because Windows Forms and WPF have different way of implementing message pumping. If you want to know all the details related to how the message loop interop between Windows Forms and WPF works, you can read the WPF documentation article: Windows Forms and WPF Interoperability Input Architecture.

  The usage of FormHost in XAML is pretty straightforward as the following XAML snippet domonstrates:

<Window x:Class="TestCode.HostingFormDemo"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
  
xmlns:cc="clr-namespace:Sheva.Windows.Interop"
  
Title="Hosting Form In WPF"
    >
    <
cc:FormHost ShowCaption="False">
      <
wf:Form/>
    </
cc:FormHost>
</
Window>

Another Way To Listen To DP Value Change

| 0 comments

Ben Constable just blogs about another elegant way to listen to dependency property change, the trick here is using DependencyPropertyDescriptor, imagine that you have a Label called myLabel, and you want to get notified when it's ContentProperty is changed, then you can do something like the following:

DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Label.ContentProperty, typeof(Label));
if (dpd != null)
{
    dpd.AddValueChanged(myLabel, delegate
    {
        // Add your logic here to respond to value change.
    });
}

The other ways in WPF that you can use to listen to property change is to subclass an existing Control, and override the metadata of a dependency property whose property change you want to listen to, when you do so, you need to specify a PropertyChangedCallback which a delegate to your property change event handler, or instead of using PropertyChangedCallback, you can override the OnPropertyChanged method, and place your logic there, as a bonus, you can get additional information things like which property is changed by examining the value of passed-in DependencyPropertyChangedEventArgs argument's Property property.