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
Related
In a WPF application, I'd like to create a textbox dynamically which will show in front of the application and be able to freely set its location by pixel. (The textbox is going to follow the mouse cursor).
This was easily done in Winforms on the fly but WPF makes things.. a little bit weird when it comes to setting a control's location by pixel since I have to add the control as a child of a container. I'm aware this is certainly doable on Canvas, but what I actually have is a dockpanel with a richtextbox to the left and a datagrid to the right.
So what are my options here? Do I have to use canvas? Can I get away with using dockpanel (or grid) to implement what I want here?
You can use a Canvas or a Grid. If you use a Canvas, set the Canvas.Left property and the Canvas.Top property. If you use a Grid, you'll need to set a size for your TextBox, set the HorizontalAlignment to Left, and VerticalAlignment to Top. To change the location of the TextBox, assign it values for MarginLeft and MarginTop.
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.
I'm looking to teach myself better methods of doing things in WPF that I would normally do manually.
In this case, I have a ViewBox with an image in it. I also have a button that uses a DoubleAnimation to rotate the image 90 to the right.
This animation works fine, but obviously because it's square as it turns, the image does a "best fit" to the ViewBox which makes the rotation look quite bad, as it gets larger and smaller as its longest edge shrinks or grows to fit to that particular rotation angle.
I am looking for any advice on the best way to handle this using appropriate WPF methods. Obviously I could do all the calculations manually, but I would be more interested in finding a way to use the controls and methods built into the .NET architecture.
Thanks for your help.
If you only have an Image in your ViewBox, drop the view box. An image is already capable of stretching correctly with the Stretch attribute set to Uniform.
In any case, use a RenderTransform instead of a LayoutTransform, to avoid recalculating the position of the controls when the images rotates. RenderTransform will rotate the object after all position calculations are done so you'll be fine. Just add a margin around the image if you find that it pass over some control while rotating.
I have made some custom attached properties that enable me to create a "pop out" effect on any control.
It animates the width and/or height when a boolean DependencyProperty is toggled.
Is there a good way to set all ScrollViewer's scrollbar visibility inside the control to hidden during this effect? You can see some ugly scrollbars appear during the animation.
I would rather not have to traverse the visual tree at the start of the animation, and then do it again when the animation completes.
EDIT: Although an alternate solution would be nice, at this point I'd rather bind to a readonly attached property named IsAnimating to handle setting the scroll visibility.
Is there a global way to to this?
Instead of animating the width of the control itself, try fixing its width at the start of the animation and reparenting it into a grid, and animate the grid's width instead. The original visual wouldn't change size in its own little world, and no scroll bars would appear or change.
I'm trying to improve the graph drawing control that comes with Graph#. It's good, but things get out of hand when you start dragging nodes around. This is my first encounter with WPF, so this is probably a newbie question. :)
I have the GraphCanvas control which has nodes and edges on it. They can be dragged around which changes their coordinates, possibly making them negative. I would like to add scrollbars to the control which would allow to see how big the canvas really is.
To this end I'm thinking of putting the GraphCanvas inside a ScrollViewer. Which would be pretty easy and straightforward if not for one problem. I may not resize the GraphCanvas itself when a node is dragged outside the borders or this will mess up dragging bad. That is also the problem with the original control (check it out, it comes with a sample application).
It would be good if I could bind the scrollbar size/location to properties of the GraphCanvas, so that the ScrollViewer would not scroll anything physically, but just set the properties of GraphCanvas. That in turn would perform all actual calculations and scrolling.
How can this be done?
OK, I found it! Three easy steps:
Implement System.Windows.Controls.Primitives.IScrollInfo on your custom control;
Add your custom control to a ScrollViewer;
Set the CanContentScroll property on the ScrollViewer to True.
Voila!
Check out this link straight from MSDN. It talks about composing several controls into a single Composite Control:
WPF: Customizing Controls for Windows Presentation Foundation