[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 95
  • Last Modified:

In WPF, how do you get the dimensions of an element on an InkCanvas?

First, thank you for your time.

I have created a wpf desktop applciation.  On the view there is an InkCanvas control.  After a png file is loaded into the canvas the user has the ability to modify this image in numerous ways.  After the user colors, resizes and moves the image around, the user then clicks the Save button.  The save button should not save the entire contents of the canvas but just the modified image that was placed on the canvas.  In order for the code to just save a small specific rectangle of the canvas, I need to know where the image is and its dimensions.  I can successfully get the width and height of the image, but I can't seem to get the top and left coordinates of the image on the canvas.

Here is the Save method:
private void Save_Click(object sender, RoutedEventArgs e)
    var filename = General.PromptForSaveFilename();
    if (filename != null)
         foreach (Image child in inkCanvas.Children)
               if (child.Source != null && child.Source.ToString().Contains(".png"))
                     var element = (UIElement) child;
                     double top = 0.0D, right = 0.0D, bottom = 0.0D, left = 0.0D;

                     GetElementDimensions(element, out top, out left, out bottom, out right);
                     // The value for left and top are 0.0!  This is the problem.

// Return the dimensions of this element.  This routine is wrong!  The top and left values are 0!?
private static void GetElementDimensions(UIElement element, out double top, out double left, out double bottom, out double right)
    top = InkCanvas.GetTop(element);
    left = InkCanvas.GetLeft(element);
    bottom = InkCanvas.GetBottom(element);
    right = InkCanvas.GetRight(element);

    // It's possible that some of the values are NaN or infinity.  Reset those values to 0.
    EnsureReasonableValue(ref top);
    EnsureReasonableValue(ref left);
    EnsureReasonableValue(ref bottom);
    EnsureReasonableValue(ref right);

// If the incoming value is not reasonable, i.e. NaN or Infinity, then set it to 0.0; otherwise leave it alone.
private static void EnsureReasonableValue(ref double value)
    if (!IsFinite(value))
        value = 0.0D;

// Return true if the incoming value is reasonable (not infinity); otherwise return false. 
public static bool IsFinite(double value)
    return !double.IsNaN(value) && !double.IsInfinity(value);

Open in new window


Again, thank you for your time.
1 Solution
Sytech SolutionsCommented:
Hi Michael

Are you using a RenderTransform to move the image on the InkCanvas? If so this is applied after the layout which would mean InkCanvas.Top and Left would be NaN if not explicitly set when the image is loaded. Assuming this is the case the following code worked for me:

<InkCanvas x:Name="inkCanvas">
    <Image Source="Image.png" Width="100" Height="100">
            <TranslateTransform X="40" Y="50" />

Open in new window

FrameworkElement element = (FrameworkElement)inkCanvas.Children[0];
TranslateTransform translateTransform = (TranslateTransform)element.RenderTransform;
double translateX = translateTransform.X;
double translateY = translateTransform.Y;
double width = element.ActualWidth;
double height = element.ActualHeight;

Open in new window

Let me know if that helps?


Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now