none
Negative left margin not tracking RRS feed

  • Question

  • Hey everybody,

     

    There is disconnect between margin left/top and canvas left/top that I would like to understand. It may just be a bug. I know I can just avoid the situation, but again, I want to know why this does not work.

     

    I have 2 ellipses rotating around a common origin. No animations, I am calculating the x,y offsets based on the angle and I am setting Margin left and top for one ellipse and Canvas left and top for the other. You would expect them to track perfectly. They do not. The one using margin, when left/top go negative is not correct, by a lot. In this case it seems 2:1 but i have seen other ratios.

     

    Left mouse 'runs' the thing and right single steps. The blue ellipse works correctly and the red only does in the ++ quardrant.

     

    Thanks in advance for any feedback.

     

    Ted

     

    <Window x:Class="BadMargin.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="BadMargin" Height="400" Width="400"

    >

    <Canvas Width="100" Height="100" Background="AliceBlue" >

    <Ellipse Width="7" Height="7" x:Name="uiEndPoint1" Fill="Red" Margin="100,0,0,0" />

    <Ellipse Width="7" Height="7" x:Name="uiEndPoint2" Fill="Blue" Canvas.Left="100" Canvas.Top="0" />

    </Canvas>

    </Window>

     

     

     

    using System.Windows.Input;

    using System;

    using System.Windows;

    using System.Windows.Threading;

    using System.Windows.Controls;

    using System.Threading;

    namespace BadMargin

    {

    public partial class Window1 : System.Windows.Window

    {

    public Window1 ( )

    {

    InitializeComponent( );

    MouseRightButtonDown += new MouseButtonEventHandler( Window1_MouseRightButtonDown );

    MouseLeftButtonDown += new MouseButtonEventHandler( Window1_MouseLeftButtonDown );

    }

    enum PlayStates { Stopped, Running, Paused, SingleStep, StepOnce };

    PlayStates PlayState = PlayStates.Stopped;

    void Window1_MouseRightButtonDown ( object sender, MouseButtonEventArgs e )

    {

    PlayState = PlayStates.SingleStep;

    Spin( );

    }

    void Window1_MouseLeftButtonDown ( object sender, MouseButtonEventArgs e )

    {

    PlayState = PlayStates.Running;

    Spin( );

    }

    double angle = 0;

    void Spin ( )

    {

    switch ( PlayState )

    {

    case PlayStates.SingleStep:

    PlayState = PlayStates.Paused;

    break;

    case PlayStates.Running:

    break;

    case PlayStates.Paused:

    return;

    }

    angle += 10;

    double x = 100 * Math.Cos( angle / ( 180 / Math.PI ) );

    double y = 100 * Math.Sin( angle / ( 180 / Math.PI ) );

    // EndPoint1 - Margin

    uiEndPoint1.Margin = new Thickness( x, y, 0, 0 );

    // EndPoint2 - Canvas.Left/Top

    Canvas.SetLeft( uiEndPoint2, x );

    Canvas.SetTop( uiEndPoint2, y );

    Thread.Sleep( 50 );

    Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new ThreadStart( Spin ) );

    }

    }

    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Thursday, April 5, 2007 2:26 PM

Answers

  • To explain the positioning of the margin based ellipse, the calculation goes like this. Let's assume that the margin is -20,0,0,0.

     

    Canvas is positioning the ellipse at 0,0 since Left and Top aren't specified. The margin is used as part of the calculation for the size of the child in addition to the specified width of 7. So, the width of the ellipse is -20 + 7 = -13. That means that the bounds for the ellipse is -13,0,0,7.

     

    For the Left positioned ellipse, it is positioned at -20,0, and its width is 7. So, the bounds of that ellipse is -20,0,-13,7.

     

    Rather strange, admittedly, which is probably why all the docs recommend positive margins. Also, using Left and Top is clearer in this case than using Margin.

     

    Ben

    Wednesday, April 11, 2007 8:37 PM

All replies

  •  

    OK, a reply to my own question. The Doc for margin does say 0 to Pos infinity. But, I am sure I have seeen negative margins in samples and, Blend will create negative margins. So I cannot yelp too much about it not working, but in all honesty it seems a very artificial limit, and the rule is ignored by the 'premiere' XAML tool.

     

    Thursday, April 5, 2007 3:10 PM
  • Margins have to be 0 or positive numbers. The Margin dependency property has a ValidateValueCallback to assure this.

    Friday, April 6, 2007 8:19 AM
  • Negative margins are allowed. At some point of the product development there was a validation for non-negative margin, but this have been removed.
    Monday, April 9, 2007 8:30 PM
  • To explain the positioning of the margin based ellipse, the calculation goes like this. Let's assume that the margin is -20,0,0,0.

     

    Canvas is positioning the ellipse at 0,0 since Left and Top aren't specified. The margin is used as part of the calculation for the size of the child in addition to the specified width of 7. So, the width of the ellipse is -20 + 7 = -13. That means that the bounds for the ellipse is -13,0,0,7.

     

    For the Left positioned ellipse, it is positioned at -20,0, and its width is 7. So, the bounds of that ellipse is -20,0,-13,7.

     

    Rather strange, admittedly, which is probably why all the docs recommend positive margins. Also, using Left and Top is clearer in this case than using Margin.

     

    Ben

    Wednesday, April 11, 2007 8:37 PM