Moving a TabControl - c#

I need to move a TabControl dynamically in code. How do I do it?
I tried setting the margin, wrapping it in a scatterviewitem (using Center, but it always returns 0,0 ), wrapping it in a canvas (in hope of using .Left and .Top) but they all didn't work. Can someone point me in the right direction?

Moving a control in WPF visually is based on the panel you used. For example, you have to adjust rows and columns if you use Grid and Top, Left properties if you used Canvas.
But a good approach is to use transformations. Use TranslateTransform to move your elements. Since transformation will not affect the layout pass.
<TabControl >
<TabControl.RenderTransform>
<TranslateTransform x:Name="translation"/>
</TabControl.RenderTransform>
</TabControl>
Adjust X and Y values in code,
translation.X = 200;

Related

Canvas.Left vs Canvas.Right

What is the difference between Canvas.Right and Canvas.Left similarly Canvas.Top and Canvas.Bottom
It is really painful when i align the controls with Canvas.Right and when i try to align in the Design mode it adds the Canvas.Left, how to prevent auto adding Canvas.Left property to a control while aligning it, as I already defined the Canvas.Right to it why it doesn't update the same property. Its really irritating when we want to do animation on controls, it reverses the direction of animation
The answer to this is don't use the visual drag&drop designer. It will do it's best but it cannot read your mind. If you know what you want, you are faster doing XAML directly, than visually designing it and then manually doing XAML optimization anyway.
Canvas.Left is the distance between left side of control and left side of Canvas and Canvas.Right is the distance of the right side from the right and analogically it's the same with Canvas.Top and Canvas.Bottom. You can read about it in Canvas attached properties. The designer is not particularly intelligent or helpful in this case. The only way is to do it manually in XAML

Differences between Canvas Property and Margin

There are any differences between using SetValue with (for example) Canvas.LeftProperty and Margin Property?
To be more clear:
<Canvas>
<Rectangle x:Name="rect">
</Canvas>
Is
rect.SetValue(Canvas.LeftProperty, 10)
equivalent to
rect.Margin = new Thickness(10, 0, 0, 0)
or not?
The Margin property is used with every element to determine extra space around the object. It works in almost all types of layouting (StackPanel, Grid, ContentControls, etc.)
The Canvas.LeftProperty (as well as Top, Right, and Bottom) only apply to elements which are directly inside a Canvas. The Canvas will use these values to determine where an object should be. With Shape elements like a Path, the Canvas also looks at the location data of the Shape when determining the position.
Technically, the Canvas attached properties should accumulate with the inherent location data of a Shape (if any) as well as the Margin. You could use all 3 to modify the position. But usually you would try to keep it simple.
For example, a Rectangle should use its Width and Height properties as well as Canvas.Left and Canvas.Top. A Path would either just rely on its point data or it would offset it with Canvas.Left and Canvas.Top. You shouldn't use margin for elements inside a Canvas since you have better control without using it, but you technically could.
For an element directly in a Canvas, the only difference is in the means. The end result is exactly the same.
When the Rectangle is positioned, the layout engine will add together all the values that affect its position. For the X coordinate this includes Canvas.Left and Margin.Left.
So in one case it is adding 10 + 0, and in the other it is adding 0 + 10.
So go with whichever you prefer. Personally I prefer Canvas.Left in this situation as it seems to make more contextual sense.
It looks same but in first case canvas moves you rect right in 10 point. In second rect moves right in 10 point.
Use one of this way according to your purposes.
EDIT: If look more deeply in WPF code. In first case rect is moved in ArrangeOverride of Canvas in second case in ArrangeOverride of Rectangle.
Canvas.Left
Canvas.Right
Canvas.Top
Canvas.Bottom
are enforced only inside the canvas container, they will not alter the width and height of your the control they're being attached to. (left=10, right=10 will not stretch to give a margin of 10 on each side)
Margin.Left
Margin.Right
Margin.Top
Margin.Bottom
Is controlled by the object that it's been set on, it will work outside of a Canvas on a grid for example and will alter the width and height of any control to enforce it's value (IF the width and height are NaN).
You can use the Margin property inside your template of the object using a TemplateBinding or regular Binding as it is a DependencyProperty. This also adjusts the width and height of the object.
The Canvas properties are attached properties to the FrameworkElement and allow positioning of elements that might not have a Margin property. And they do not work if the object does not have a Canvas parent.

Estimate position and Width/Height of rendered UserControl

I have a UserControl (boxes) that can have varying size based on the number of items in its ItemsControl.
Many such usercontrols are added to a Canvas programmatically.
I need to draw arrows interconnecting these usercontrols. What is the best way to get the origin coordinates of the control w.r.t the Canvas and the rendered Width/Height so that I can figure out the arrow start and endpoints.
Canvas provides the coordinates of each control via Canvas.Left and Canvas.Top attached properties - which you know if you positioned them yourself anyway. So the (slightly) harder part is getting the other coordinate, and for that you want to know the rendered height/width. ActualHeight and ActualWidth give you this, assuming the control has already been laid out:
double top = Canvas.GetTop(control)
double bottom = top + control.ActualHeight
double left = Canvas.GetLeft(control)
double right = left + control.ActualWidth
If you're doing this before the controls have had a chance to be rendered on the screen, you can first do control.UpdateLayout() (or control.Measure()) to ensure the layout system measures their size.

WPF: How to find space available for Canvas?

I'm using WPF shapes to create Hexagons (for a game map) on a Canvas. After some playing around with ScrollViewer, I've decided to implement the scrolling and zoom of the map myself rather than using WPF functionality, just using WPF to get the events for mouse wheel, arrow keys etc. I'm placing the (Hex Map) Canvas as the last child inside a Dock Panel so it will get all the available remaining space. The Dock Panel will be set to be the content of the Main Window. But I want to find out how big the Canvas can be before I put any Children on the Canvas so that I can centre the screen over the Hex I want and only add the Shapes (Hexs) that can actually be seen. When zoomed out, a long way I will remove Polygons altogether and use another method of rendering and when zoomed in a long way I will add more details.
Is there any neat way of getting the available space? The only way that I can think of that will hopefully work is to get the current dimensions of the windows and subtract the dimensions of the outer elements of the Dock Panel, but that feels rather messy.
You may use the ActualWidth and ActualHeight properties of Canvas to determine size available to it. Be sure that HorizontalAlignment and VerticalAlignment are set to Stretch.

Use XAML data binding to bind each end of a Line to the center of two shapes on a Canvas

I have a Canvas in Silverlight with two ellipses on it. The ellipses are animated via events in the code behind. I have added a line two the canvas and I would like each end of the line to be bound to the center of each ellipse. Is it possible to do this in XAML databinding or will I have to manually move the end of the line around in code?
While I haven't tried it, you may be able to achieve something using an ElementName Binding to bind between the Canvas.Top (and Left) properties of the ellipse and the line. You'll probably need a converter to offset that to center of the ellipse.

Categories