Converting WPF Apps to Surface Apps – Part 1

April 18, 2009

I have found myself converting WPF apps to Surface apps quite often lately.  Most of the necessary changes are fairly obvious, but I encountered one lately I thought I would share with you.  In WPF apps there is functionality to capture the mouse cursor, but in Surface we have no mouse.  So we need to perform the analogous catch of a finger (or whatever else you like) contact.  Below is the first method I needed to change in a recent project:

private void OnMouseDown(object sender, MouseButtonEventArgs args)

{

UIElement source = sender as UIElement;

Point p = args.GetPosition(source);

if (a boolean)

{

this.CaptureMouse();

}

else

return;

}

By the way, “this” is a ContentControl.  Notice the this.CaptureMouse() line?  Clearly this needs to change for surface.  There is no this.CaptureFinger() on a SurfaceContentControl (that would be way too easy).  So I modified the above code to the following:

private void SurfaceContentControl_ContactDown(object sender, ContactEventArgs e)

{

UIElement source = sender as UIElement;

Point p = e.GetPosition(source);

if (a boolean)

{

e.Contact.Capture(this);

}

else

return;

}

So in this case I switched:

this.CaptureMouse();
for this:

e.Contact.Capture(this);

That was easy enough.  Let’s try another.

private void OnMouseMove(object sender, MouseEventArgs args)

{

UIElement source = sender as UIElement;

Point p = args.GetPosition(source);

if (!(sender as UIElement).IsMouseCaptured)

{

//Do some stuff

}

}

Which I changed to:

private void SurfaceContentControl_ContactChanged(object sender, ContactEventArgs e)

{

UIElement source = sender as UIElement;

Point p = e.GetPosition(source);

if ((sender as UIElement) != e.Contact.Captured)

{

//Do some stuff

}

}

So in this case I changed:

if (!(sender as UIElement).IsMouseCaptured)
into this:

if ((sender as UIElement) != e.Contact.Captured)

We’re on a roll here, let’s do another:

private void OnMouseUp(object sender, MouseButtonEventArgs args)

{

if (this.IsMouseCaptured)

{

UIElement source = sender as UIElement;

Point p = args.GetPosition(source);

if (a boolean)

//Do something

this.ReleaseMouseCapture();

}

}

Turns into this:

private void SurfaceContentControl_ContactUp(object sender, ContactEventArgs e)

{

if (this.IsAnyContactCaptured)

{

UIElement source = sender as UIElement;

Point p = e.GetPosition(source);

if (a boolean)

//Do something


this.ReleaseAllContactCaptures();

}

}

Now you know how to change mouse capture logic in old WPF apps into new finger capture logic.  Please feel free to comment if you know how I could improve this.