nikhil
nikhil

Reputation: 1736

Canvas getRight method returns Nan

I have a Rectangle that I am trying to drag and drop inside a Canvas. After the drag is complete I want to get the left, top, right and bottom coordinates. For that when I say Canvas.GetRight(dragableThumb) and Canvas.GetBottom(dragableThumb) it returns NaN for both the values.

So for the right and bottom I am saying something like this, but the problem is I get wrong values. Please help.

var right = this.Width - left - dragableThumb.ActualWidth; var bottom = this.Height - top - dragableThumb.ActualHeight;

Here is the entire code.

xaml:

<Window.Resources>
        <ControlTemplate x:Key="myDragableCT">
            <Rectangle 
x:Name="Arrow" 
Height="94" RenderTransformOrigin="0.5,0.5" Width="128">
                <Rectangle.Fill>
                    <SolidColorBrush Color="Green" />
                </Rectangle.Fill>
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                        <SkewTransform AngleX="0" AngleY="0"/>
                        <RotateTransform Angle="0"/>
                        <TranslateTransform X="0" Y="0"/>
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>
        </ControlTemplate>
    </Window.Resources>
    <Canvas x:Name="DragableCanvas">
        <Thumb x:Name="dragableThumb" DragDelta="DragableThumb_DragDelta" DragCompleted="DragableThumb_DragCompleted" Canvas.Left="331"
                   Canvas.Top="112" Template="{StaticResource myDragableCT}"></Thumb>
    </Canvas>
</Window>

Code Behind:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void DragableThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            Canvas.SetLeft(dragableThumb, Canvas.GetLeft(dragableThumb) + e.HorizontalChange);
            Canvas.SetTop(dragableThumb, Canvas.GetTop(dragableThumb) + e.VerticalChange);
        }

        private void DragableThumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            var left = Canvas.GetLeft(dragableThumb);
            var top = Canvas.GetTop(dragableThumb);
            var right = this.Width - left - dragableThumb.ActualWidth;
            var bottom = this.Height - top - dragableThumb.ActualHeight;
            MessageBox.Show(string.Format("left:{0}, top:{1}, right:{2}, bottom:{3}", left, top, right, bottom));
        }
    }

Upvotes: 0

Views: 992

Answers (2)

walterlv
walterlv

Reputation: 2376

Canvas.Left, Canvas.Top, Canvas.Right and Canvas.Bottom are layout properties instead of render properties. The four properties are used to limit the layout of the UIElements but not presents the layout states And this behavior is the same as the Width and Height properties.

<Grid>
    <Button x:Name="DemoButton" />
</Grid>

See this code above, if we read the Width and Height properties, we'll find that they are both double.NaN. Only if we read the ActualWidth, ActualHeight or RenderSize properties we can get the correct layout states.

The same as the Canvas.Left, Canvas.Top, Canvas.Right and Canvas.Bottom properties. You can get the right and the bottom by using other methods, such as:

var right = Canvas.GetLeft(dragableThumb) + dragableThumb.ActualWidth;
var bottom = Canvas.GetTop(dragableThumb) + dragableThumb.ActualHeight;

If you want a method for all other situations you can try this code below:

var bounds = new Rect(
    dragableThumb.TranslatePoint(default, DragableCanvas),
    dragableThumb.TranslatePoint(new Point(dragableThumb.ActualWidth, dragableThumb.ActualHeight), DragableCanvas));
var right = bounds.Right;
var bottom = bounds.Bottom;

By the way, you spelled the wrong dragable. The correct spell is draggable.

Upvotes: 1

Keith Stein
Keith Stein

Reputation: 6724

It should be:

var right = left + dragableThumb.ActualWidth;
var bottom = top + dragableThumb.ActualHeight;

Upvotes: 1

Related Questions