azamsharp
azamsharp

Reputation: 20096

Changing Position of an Element Programmatically in WPF

I did not knew that this simple thing would be slightly complicated. I have a Canvas in which I am trying to add Ellipse dynamically. Here is the code:

<StackPanel>

        <Canvas Name="canvas" Background="LightBlue" Margin="5" Width="250" Height="250">

        </Canvas>

        <Button Content="Draw Images" Click="Button_Click" Width="100" Margin="10" />

    </StackPanel>

And here is the code behind:

private void Button_Click(object sender, RoutedEventArgs e)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Fill = Brushes.Red;
            ellipse.Width = 10;
            ellipse.Height = 10;

            ellipse.SetValue(Canvas.LeftProperty,100);
            ellipse.SetValue(Canvas.TopProperty,100);

            canvas.Children.Add(ellipse); 


        }

For some reason it throws the exception that 100 is not a valid value!

Upvotes: 23

Views: 50541

Answers (6)

if you want to move your canvas with matrix you should do like this :

<Canvas Name="mcanvas" >
   <Canvas.RenderTransform>
     <MatrixTransform x:Name="mt"/>
   </Canvas.RenderTransform>
</Canvas>

then you can do all works you want, on Matrix "mt". Like this :

For Scale:

Matrix matrix = new Matrix();
matrix.Scale(1.5, 1.5);
mt.Matrix = matrix;
mcanvas.LayoutTransform = Transform.Identity;

For Translate ( Changing Position ) :

Matrix matrix = new Matrix();
matrix.Translate(50, 0);
mt.Matrix = matrix;
mcanvas.LayoutTransform = Transform.Identity;

And if you want to create a canvas element programmatically, you should do like this :

Ellipse el = new Ellipse();
Matrix matrix = new Matrix();
matrix.Translate(50, 0);
matrix.Scale(1.5,1.5);
el.RenderTransform = new MatrixTransform(matrix);

Hope this helps you.

Upvotes: 1

George Birbilis
George Birbilis

Reputation: 2940

The Left and Top are attached properties owned by Canvas class, that you can attach to any DependencyObject, whether it is a FrameworkElement or not and whether it is hosted in a Canvas or not.

That's why you have to use:

myDependencyObject.SetValue(Canvas.LeftProperty, leftValue); myDependencyObject.SetValue(Canvas.TopProperty, topValue);

Most other containers, say the Grid will just ignore those property values, if our dependency object is a FrameworkElement contained in them instead of inside a Canvas. One could make though other containers that respect those properties

Upvotes: 0

azamsharp
azamsharp

Reputation: 20096

Here is the answer:

Canvas.SetLeft(ellipse,GetRandomValue());
Canvas.SetTop(ellipse,GetRandomValue());

Upvotes: 34

Ray
Ray

Reputation: 3109

The reason 100 doesn't work is that SetValue() interprets it as an integer, but Canvas.Top & Canvas.Left are doubles. Try 100d instead. Also SetLeft() & SetTop() work because they expect doubles.

Upvotes: 15

AndyW360
AndyW360

Reputation: 91

The code below works:

ellipse.SetValue(Canvas.LeftProperty,100.0);
ellipse.SetValue(Canvas.TopProperty,100.0);

The values are of the double type.

Upvotes: 9

Bobo
Bobo

Reputation: 1

Try to convert integer type to Double type using "CDbl" function

Try this:

ellipse.SetValue(Canvas.LeftProperty,Cdbl(100));

Upvotes: -6

Related Questions