I recently encountered an error where I was not getting MouseMove events for a Canvas that was within a StackPanel.

The first problem is that, if the background is not set to anything, there will be no events transmitted. A simple solution is just to set the background to transparent or white (or whatever color you want).

The second problem, which took me forever to figure out, stems from the fact that the Canvas width was 1 pixel (or was it 0?) once I put it into my StackPanel. However, this does not keep elements in the Canvas from appearing outside this 1-pixel wide region, so it appears as if the width of the Canvas is greater. So the important thing to realize is that the Canvas will only respond to events that are within the area covered by its width/height.

I’ve had this problem several times where my Windows XP installed on a Boot Camp partition on my Macbook will suddenly freak out and start using 100% CPU and generally being very unresponsive. Thanks a tip from a friend I found a very easy fix: reboot into MacOS, and then boot into Windows XP again.

It seems that other people have the same problem as well.

Sometimes in WPF you might want to create a class that has a Child and that somehow changes the presentation of the Child, perhaps by scaling it or translating it. And example is the Viewbox class, which scales your content to fit the window. You could do this just by modifying the RenderTransform or LayoutTransform of the Child. However, if you want this be a general, reusable class, you probably shouldn’t touching those properties of your Child, in case someone else might want to.

The solution is to add another node in the hierarchy, so you have:

(your custom class) –> (a private container class) –> Child

Then, you could just modify the container class’s transforms, and it would affect the presentation of the Child. I coded up a trivial example which scales everything 2x:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Model
{
    class ZoomAndPan : Decorator
    {
        Decorator _container;

        public ZoomAndPan()
        {
            _container = new Decorator();
            AddVisualChild(_container);
            AddLogicalChild(_container);

            _container.RenderTransform = new RotateTransform(45);
        }

        public override UIElement Child
        {
            get { return _container.Child; }
            set { _container.Child = value; }
        }

        protected override int VisualChildrenCount
        {
            get { return _container != null ? 1 : 0; }
        }

        protected override Visual GetVisualChild(int index)
        {
            if (index > 0 || _container == null)
                throw new ArgumentOutOfRangeException("index");

            return _container;
        }

        protected override Size MeasureOverride(Size sizeAvailable)
        {
            _container.Measure(sizeAvailable);
            return _container.DesiredSize;
        }

        protected override Size ArrangeOverride(Size sizeArrange)
        {
            _container.Arrange(new Rect(new Point(0, 0), sizeArrange));
            return sizeArrange;
        }

        [STAThread]
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.Fill = Brushes.Bisque;
            r.Width = 200;
            r.Height = 200;

            Canvas canv = new Canvas();
            canv.Children.Add(r);

            ZoomAndPan zp = new ZoomAndPan();
            zp.Child = canv;

            Window w = new Window();
            w.Content = zp;

            new Application().Run(w);
        }
    }
}