Reputation: 382
How can change runtime position of a canvas in which dynamically I added controls like (labels, lines)?
I can zoom canvas with all controls but I can't move in another position with MouseMove, MouseUp, MouseDown.
<Canvas Name="canvas" Width="1000" Height="400"
Margin="100 0 0 50"
Background="White"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
MouseWheel="Canvas_MouseWheel"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp"
MouseDown="Canvas_MouseDown">
<Canvas.RenderTransform>
<ScaleTransform x:Name="st" />
</Canvas.RenderTransform>
</Canvas>
I find this code in internet but for my case is not working
bool activated;
Point point;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
activated = true;
point = Mouse.GetPosition(canvas);
Mouse.Capture(canvas);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (activated)
{
double top = Canvas.GetTop(canGraph) + Mouse.GetPosition(canvas).Y - point.Y;
Canvas.SetTop(canvas, top);
double left = Canvas.GetLeft(canvas) + Mouse.GetPosition(canvas).X - point.X;
Canvas.SetLeft(canvas, left);
point = Mouse.GetPosition(canvas);
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
activated = false;
Mouse.Capture(null);
}
Upvotes: 2
Views: 11466
Reputation: 1
After mouse down then again I move the canvas is start to move from first position when is been.
P.s.
I add this for more stable code , but always return back to the first position
private void Canvas_MouseLeave(object sender, MouseEventArgs e)
{
activated = false;
}
Upvotes: 0
Reputation: 1306
Edit - The previous solution that I provided was not going to work after the first move of the element without more code so here's a better one
In order to be working correctly the canvas element have to be aligned to the coordinate system of it's parent, which we achieve as we put the canvas in top left corner, if you don't put it there you have to calculate the difference yourselve.
Code behind
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
canvas.CaptureMouse();
}
Stopwatch sw = new Stopwatch();
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (canvas.IsMouseCaptured)
{
translate.X = e.GetPosition(container).X;
translate.Y = e.GetPosition(container).Y;
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
canvas.ReleaseMouseCapture();
}
XAML
<Grid Background="Green" x:Name="container">
<Canvas Name="canvas" Width="100" Height="100"
Margin="0 0 0 0"
Background="Purple"
VerticalAlignment="Top"
HorizontalAlignment="Left"
MouseMove="Canvas_MouseMove"
MouseDown="Canvas_MouseDown">
<StackPanel Background="White">
<TextBlock >asdasda</TextBlock>
<TextBlock >cccc</TextBlock>
<TextBlock >aaaaa</TextBlock>
<TextBlock >bbbb</TextBlock>
</StackPanel>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st" />
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
Original answer
XAML
I'd do something like this:
Add a translate transform and to keep you previous transform put it in a group
Use translate transform in order to move the canvas with positions from the mouse events
For starting point of your translations you can use coordinates in the container
Code behind:
bool activated;
Point point;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
activated = true;
point = e.GetPosition(container);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (activated)
{
translate.X = e.GetPosition(container).X - point.X;
translate.Y = e.GetPosition(container).Y - point.Y;
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
activated = false;
}
XAML
<Canvas Name="canvas" Width="100" Height="100"
Margin="0 0 0 0"
Background="Purple"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp"
MouseDown="Canvas_MouseDown">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st" />
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
Upvotes: 5