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

Posted on 2014-08-20
Last Modified: 2016-06-21
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.
Question by:MichaelDavidCarr
    1 Comment
    LVL 2

    Accepted Solution

    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?


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
    This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
    This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…
    how to add IIS SMTP to handle application/Scanner relays into office 365.

    761 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now