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.
Related
In my WPF application I have a control that acts like a zoom box. You can zoom and drag its content. In my case this content is a grid that contains an image and some UserControls. These UserControls have to be positioned ontop of the image to highlight some segments of that image.
Here is an example (this is not an actual use case):
My question is, how should I position those red rectangles (what is the better practise here)?
By replacing the grid with a canvas and use Canvas.SetLeft resp. Canvas.SetTop?
or
By manipulating the RenderTransform of those rectangles?
Note: The rectangles are interactive (they have to interact with the mouse and maybe some other input devices).
What would be the best way to make a WinForms application fully scalable, for example when the Form resizes?
In WPF i would use something like a Viewbox and/or a UniformGrid, but something like this doesn't exists in WinForms.
Is there an easier (and maybe faster) way to rescale controls on a from after resizing it, instead of resizing them all by calculating their new Size/Location etc.?
Thanks in advance
In Windows Forms, you use the Anchor and Dock properties for each control.
Here's an article about using them: http://www.techrepublic.com/article/manage-winform-controls-using-the-anchor-and-dock-properties/
You should also look at FlowLayoutPanel and TableLayoutPanel
you can use anchor and dock, depending on your need:
Anchor - the edges of the container to which a control is bound and determines how a control is resized with its parent.
Dock - which control borders are docked to its parent control and determines how a control is resized with its parent.
for further read: Dock and Anchor
Have a look at the Anchor property found on pretty much any control. This allows you to lock a control to any (or all) of the four borders of a window.
Once one distance is anchored (e.g. Top or Right), the control will always try to keep that distance, no matter how you resize your window.
For example, you'd set Anchor to Bottom and Right for a button that is supposed to always stay in the bottom right corner of a window. A text box, that should always fill the window from left to right would use Left and Right.
Similar things can be achieved utilizing Dock, but a docked control will always try to fill as much space as possible (there are different strategies available, like "fill everything from here and upwards) based on its container. Depending on your use case, this can however be a lot harder to control (and I usually only use it if I want a single control to fill a full window, e.g. a TextBox).
If you need more complex alignment, like widths scaled on some kind of ratio (e.g. 30%), then there are several different containers available.
In my Winforms application, i have a User Control which serves as a 'screen' to draw various 2D shapes.
i have set its 'AutoScroll' property to true, and scrollbars works fine when you zoom the screen( i.e. User control)
Now, when i select any shape ( like rectangle or circle etc) and move it so that it goes beyond visible part of screen, i want respective scroll bars to auto slide in order to keep that shape on the visible area of screen.
do i need to set any other property of scrollbar ??
I don't think it is possible to achieve that without creating your own method.
You can set your scrollbar positon with:
this.VerticalScroll.Value = Y;
Then you have to find out the position of your Rectangle via:
Rectangle.Location.Y;
So this should work for your vertical scrollbar:
this.VerticalScroll.Value = Rectangle.Location.Y;
horzontal:
this.HorizontalScroll.Value = Rectangle.Location.X;
Combined with a MouseDown-Event it will do the trick.
Take a look here at the MSDN documention on exactly what the AutoScroll property is and does. It simply will enable the container to have a virtual size that is larger than its visible boundaries. It doesn't actually do the scrolling for you.
If you want the control to "move" with the user as they drag a shape, you will have to capture that action on your own and manually scroll the control over. I'd suggest starting with the MouseDown and MouseMove events. You'll need some logic to figure out when scrolling is needed and how much to actually scroll.
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.
is it true: a motion animation always based on a Canvas element – the Element which move is addressed via attached Property? Unfortunately it’s not possible to resize a Canvas-Element at Runtime!? So the Motion gets wrong when the user maximize the Window.
How can I create a motion animation which is scalable in WPF / C#?
Thanks a lot.
Draw your elements on the Bitmap,
and than draw your Bitmap with scale as you want
If you try resize not the self drawed elements, you can use "Viewbox" - content decorator that can stretch and scale a single child to fill the available space.
Here you can see how it works:
http://www.wpftutorials.com/2011/04/wpf-viewbox.html