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.
Related
I'm working on a .NET 3.5 desktop application written in C#. It's complex UI is populated dynamically. One part of it is the following group box which is contained in a FlowLayoutPanel and the FlowLayoutPanel is contained in a UserControl. The screenshot is taken from the design view:
When I launch the application, all controls get stretched:
Even I'm fixing the widths of each UserControl's size when Load event of the UserControl is called. The AutoSize property of all of the controls inside the group box is false.
Why is this happening and how to prevent this? I want the UI look exactly like the design view.
EDIT
The best answer to this question didn't solve my problem. Firstly, setting the border style to FixedX creates an undesirable border. Secondly, the inner controls still expanded and they are clipped by the border.
Make AutoScaleMode "Inherit" for all children user control.
You can play in the Anchor property
If you want to keep the Label in its place as the design => use combination : Top, Left
If you want to stretch the control horizontally => use combination : Top, Left , Right
If you want to keep the control to stretch the control in all directions => use combination : Top, Left, Right, Bottom
If you want to keep the control in the Bottom right position ( usually used for buttons) => use combination: Bottom, Right
You might read more about Anchor here and here
Hope this will help you
Set the WrapContents property of your FlowLayoutPanel to true
Please notify my if this worked or not
Check EnableVisualStyles property value set at application level. Set it to true and check.
If your button gets wider when you enlarge its container object, the button must be surely anchored to the left and right borders of the container. Just anchor it to the top or bottom, but not to the left or right borders.
Conversely, if your button gets higher, don't anchor it to the top or bottom.
I have a panel and I need to draw a horizontal chart on it. But sometimes the chart can be too long for the panel, even the form has maximum size. So I want to make a horizontal bar on panel to enable the user to see the remaining part of the drawing that is out of the bounds.
Chart is something like this:
As you can see, the chart is out of the panel's bounds and form's too. I don't have any idea how can it be done, so I have no code to show. So how can I do it using a basic method?
Yes, the solution is pretty basic, as long as the size you want to draw won't go over 32k pixels width:
Put your Panel inside another one.
The outer Panel has AutoScroll=true
The inner one where you draw has the size of your drawing.
You need to draw in the Paint event, as you should anyway (!)
Now the outer Panel shows a horizontal scrollbar and the user can scroll right and left and see all parts of the drawing..
One alternative would be to add a dummy control that enforces the AutoScroll of your drawing Panel to work, but I find using two Panels the cleaner way to go..
Note: You should either use a PictureBox or at least a double-buffered Panel subclass to avoid flicker and tearing:
class DrawPanel : Panel
{
public DrawPanel()
{ DoubleBuffered = true; }
}
Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.
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.
Imagine a bar graph with horizontal bars that may be very wide. I have a Panel on a Form where I want to display these bars and scroll and zoom them. The Form, and thus the Panel, can be resized. The bars are dynamically created from a database. Each time the user zooms in or out, all bars have to be created anew to adjust their sizes on the Panel.
I use Label controls to create these bars, but the problem applies to all other controls as well: If I zoom in far enough, my bars will eventually exceed the magic 16 bit border of control sizes (>65536 pixels). This makes it impossible to simply create all the controls on the panel at start and let the panel handle the scrolling.
My idea: Clear the Panel of all bar controls and create only the ones that are visible in the current view window, according to the current position of the scroll bars and the zoom level. The bars exceeding far from the visible view will be cut short just outside the Panel, so their maximum size is limited by the Panel size.
My questions:
At which Panel event(s) should this clear/create process take place best?
There could be thousands of controls, so it should be as seldom as possible.
Is there a better way to handle this? Maybe I got it all wrong from the start.
This problem arises not only with huge controls but also when smaller controls are very far apart (>65536 pixels) on a Panel, so I think a good solution may be helpful for many projects.
I wouldn't like to have to create / destroy controls, or hide / resize controls just for their click events. It's quite easy to create a UserControl and override the OnPaint method to draw the bars, and override the OnClick or OnMouseXxx events.
Since you already know the positions of the bars in "virtual space", it's easy to map the location of the mouse cursor to a bar (or a click outside a bar).
I know you said winforms is Mandatory, but I really think you should look into the wpf viewbox. You can host a wpf element in winforms. So everything else can be forms related, and you have a panel that hosts and displays your controls. I could write up a quick example that might demonstrate this for you, but if you have no intent of going this way I really don't want to waste my time.
You could create a metafile (vector graphics), show that in an image control, and manually determine which logical element is clicked.
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.