Tuesday, January 04, 2011

Updates to Kent Boogaart's Resizer control

I've used and abandoned the Resizer control a few times over the last couple years for various reasons. This time it seems it will be finding a permanent home in one of my apps. I had to make a modification to it and Blogger says I have too much text for a comment, so I'll make a new post.

I'm using Resizer inside a docking panel, so I wanted the width to stay tied to its parent panel. With that use case, I've added North, South, East, and West to the ResizeDirection enum. It's a pretty simple change, so I'll just post a few parts that people might miss if they wanted to reproduce it.


private static void OnUpdateSizeCommand(object sender, ExecutedRoutedEventArgs e)
{
Resizer resizer = sender as Resizer;
Debug.Assert(resizer != null);

if (resizer._frameworkElement != null)
{
Point point = resizer._frameworkElement.PointToScreen(Mouse.GetPosition(resizer._frameworkElement));
//If we're not adjusting the width or height, we want to leave it alone so it has its default sizing characteristics
double? widthDelta = null;
double? heightDelta = null;

switch (resizer.ResizeDirection)
{
case ResizeDirection.North:
heightDelta = resizer._resizeOrigin.Y - point.Y;
break;
case ResizeDirection.East:
widthDelta = point.X - resizer._resizeOrigin.X;
break;
case ResizeDirection.South:
heightDelta = point.Y - resizer._resizeOrigin.Y;
break;
case ResizeDirection.West:
widthDelta = resizer._resizeOrigin.X - point.X;
break;
case ResizeDirection.NorthEast:
widthDelta = point.X - resizer._resizeOrigin.X;
heightDelta = resizer._resizeOrigin.Y - point.Y;
break;
case ResizeDirection.NorthWest:
widthDelta = resizer._resizeOrigin.X - point.X;
heightDelta = resizer._resizeOrigin.Y - point.Y;
break;
case ResizeDirection.SouthEast:
widthDelta = point.X - resizer._resizeOrigin.X;
heightDelta = point.Y - resizer._resizeOrigin.Y;
break;
case ResizeDirection.SouthWest:
widthDelta = resizer._resizeOrigin.X - point.X;
heightDelta = point.Y - resizer._resizeOrigin.Y;
break;
default:
Debug.Fail("Unexpected ResizeDirection: " + resizer.ResizeDirection);
break;
}

//update the width and height, making sure we don't set to below zero
if (widthDelta != null)
resizer.Width = Math.Max(0, resizer._originalWidth + widthDelta.Value);
if (heightDelta != null)
resizer.Height = Math.Max(0, resizer._originalHeight + heightDelta.Value);
}

e.Handled = true;
}



in GripAlignmentConverter.Convert:


switch (orientation)
{
case Orientation.Horizontal:
if (resizeDirection == ResizeDirection.NorthEast ||
resizeDirection == ResizeDirection.SouthEast ||
resizeDirection == ResizeDirection.South ||
resizeDirection == ResizeDirection.North)
{
return HorizontalAlignment.Right;
}
else
{
return HorizontalAlignment.Left;
}
case Orientation.Vertical:
if (resizeDirection == ResizeDirection.NorthEast ||
resizeDirection == ResizeDirection.NorthWest ||
resizeDirection == ResizeDirection.North)
{
return VerticalAlignment.Top;
}
else
{
return VerticalAlignment.Bottom;
}
}



new cases in GripCursorConverter.Convert


case ResizeDirection.North:
case ResizeDirection.South:
return Cursors.SizeNS;
case ResizeDirection.West:
case ResizeDirection.East:
return Cursors.SizeWE;



in GripRotationConverter:


switch (resizeDirection)
{
case ResizeDirection.SouthWest:
return 90;
case ResizeDirection.NorthWest:
case ResizeDirection.West:
return 180;
case ResizeDirection.NorthEast:
case ResizeDirection.North:
return 270;
}



If I've left something out or you're having problems, let me know.