You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中Canvas.GetRight返回NaN,拖拽Thumb后坐标计算错误求助

Fixing Canvas.GetRight()/GetBottom() NaN & Incorrect Coordinate Calculation in WPF Drag Scenario

Hey there! Let's break down why you're seeing those NaN values and fix that coordinate calculation issue with your draggable Thumb (template as Rectangle) in a Canvas.

Why Canvas.GetRight() and Canvas.GetBottom() return NaN

This is totally expected WPF behavior! When you position elements in a Canvas, you typically use Canvas.Left and Canvas.Top properties to set their top-left corner position. WPF only tracks Canvas.Right and Canvas.Bottom if you explicitly assign values to them. Since you're dragging the element (which modifies Canvas.Left/Canvas.Top under the hood), those right/bottom properties are never set—hence the NaN return values.

Why your manual calculation was wrong

Your formula assumed the element was positioned using Canvas.Right/Canvas.Bottom, but that's not the case here. When using Canvas.Left/Canvas.Top, the right edge of the element is simply the left position plus the element's actual width, and the bottom edge is the top position plus the element's actual height. Your original formula subtracted values from the Canvas width/height, which would only apply if you were using right/bottom-based positioning.

The Correct Solution

Here's how to get accurate left, top, right, and bottom coordinates after dragging:

Step 1: Handle the DragCompleted Event

In your code-behind, use the Thumb.DragCompleted event to capture the final position once dragging stops:

private void DragableThumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
    var dragableThumb = sender as Thumb;
    if (dragableThumb == null) return;

    // Get the top-left position from Canvas
    double left = Canvas.GetLeft(dragableThumb);
    double top = Canvas.GetTop(dragableThumb);

    // Calculate right and bottom using the element's actual rendered size
    double right = left + dragableThumb.ActualWidth;
    double bottom = top + dragableThumb.ActualHeight;

    // Use your coordinates as needed
    Console.WriteLine($"Final Position - Left: {left:F2}, Top: {top:F2}, Right: {right:F2}, Bottom: {bottom:F2}");
}

Key Notes

  • Always use ActualWidth and ActualHeight instead of Width/Height—these properties give you the rendered size of the control, which is critical if your Thumb (or its template Rectangle) uses dynamic sizing (like Auto).
  • This calculation works regardless of the Canvas's size, because we're measuring relative to the element's top-left corner (set by Canvas.Left/Canvas.Top), not the Canvas's edges.
  • If you ever need to set Canvas.Right/Canvas.Bottom explicitly (for right-aligned positioning), you could do so in the drag handler—but for most drag scenarios, sticking with Left/Top is simpler.

Quick Check for Your XAML

Just to confirm, make sure your Thumb is properly placed in the Canvas and has its drag behavior set up. For example:

<Canvas x:Name="MainCanvas" Width="800" Height="600">
    <Thumb x:Name="DragableThumb" DragDelta="DragableThumb_DragDelta" DragCompleted="DragableThumb_DragCompleted">
        <Thumb.Template>
            <ControlTemplate>
                <Rectangle Width="100" Height="100" Fill="Blue" Stroke="Black"/>
            </ControlTemplate>
        </Thumb.Template>
    </Thumb>
</Canvas>

And your DragDelta handler should update the Canvas.Left/Canvas.Top values:

private void DragableThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
    var thumb = sender as Thumb;
    if (thumb == null) return;

    Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange);
    Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
}

That should resolve both the NaN issue and the incorrect coordinate values!

内容的提问来源于stack exchange,提问作者nikhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:22:36