UserControl ClientRectangle is smaller than it says - c#

I am trying to make my UserControl with custom borders (I changed default border style to "none" in properties - I created control and I am invoking Graphics.DrawRectangle(...,ClientRectangle). And what I see is only the top and left borders of my painted rectangle - it seems that real size of the area where I can draw is different than ClientRectangle... How to change it / get the right ClientRectangle size?

ClientRectangle returns the rectangle in exclusive coordinates so you need to subtract 1 from the bottom and right hand sides. This will work regardless of how many units per pixel there are in the current graphics mode, someone correct me if I am wrong.

Related

Find the center of a set of graphics

I have a form with a panel where a set of complex graphics are painted (represented by blue circles in the image):
The graphics are painted using DrawLine and DrawEllipse methods of the Graphics class.
I need to find the global center of the set of graphics (yellow point on the image) so that I can apply some transformations afterwards, like centering the set of graphics on the panel.
The most direct workaround I can think of is finding the boundaries of the graphics, so they are contained in a rectangular frame (red box on the image) and then divide the frame's width and height by two.
But how can I achieve this? Is there a method that would allow me to find the top, bottom, left and right boundaries of the entire set of graphics?
I'm not aware of any method in Graphics to do what you're looking for, but rolling your own should be relatively easy assuming you know the dimensions of each component image. The various DrawEllipse methods each take a bounding rectangle in some form, so you've already got all of the information that you need.
The most straightforward approach would be to simply keep track of the farthest left, right, top, and bottom bound of each image as you draw it and then form the complete bounding rectangle from those dimensions. You'll also need to account for the width of the Pen that you're using to draw your images.
As an alternative, you might want to take a look at the GraphicsPath class. GraphicsPath.GetBounds would more or less give you what you're looking for. If GraphicsPath doesn't work for you, then I think you're probably stuck writing your own code.

Scale an irregular shape to irregular bounds

I am attempting to make a reusuable, XAML, icon. It is composed of three parts.
Background, Bezel and Graphic Path objects. The shape is of a rectangle with the top right corner cut off, the bezel is same shape with the middle cut out and a margin of 1.
I need the graphic path to fit inside of this with a slight margin.
I would like it to be intelligent enough to scale itself to fit within the confines of the bezel regardless of it's shape. Like ClipToBounds only I don't want the graphic to clip - I would like it to scale.
I initially thought setting the Margin would work, however, setting the Margin of the graphic is based on a Rectangle and not the irregular shape of the bezel; so graphics with a more rectangular shape are often touching or too close to the right-side cut off of the bezel.
Does anyone have any ideas on how I might achieve this kind of ScaleToBounds behavior?
EDIT:
Please see attached pictures for an example of the problem. Both graphics are contained inside a ViewBox with a Margin. The circular graphic is the ideal margin I would like to see around the graphic. The rectangular graphic is too close to the bezel - I would like to have graphics such as the rectangular graphic scale themselves down slightly so they fit within the bezel with some margin.
rectangular graphic http://s11.postimage.org/a5v05ve2n/rectangular.png
circular graphic http://s11.postimage.org/do7029eyn/circular.png

How can I draw a square around an object, like this, in my GUI editor?

I want to write a GUI editor in C# for AutoIt, but I am not good enough with C#. I want to draw a square (focused) around an object when any object in the GUI is pressed. Like this:
Is there any library to make easier to write this kind of thing?
Square is drawn with one of DrawRectangle functions. Each of them requires a pen. Usually we use ordinary solid pen, but you need a pen with changed DashStyle property. For dotted lines change this property to DashStyle.Dot. You can also experiment with DashPattern property.
To draw little squares around the big square you need one of FillRectangle functions. Each of them requires a brush. You need a white brush, which is conveniently predefined for you to use. After filling a rectangle, you have to draw a rectangle over it with the same dimensions. These two functions together give an impression of empty and lined rectangle.
To make little squares a little rounded, like they are in the image, you have to change a pen parameter used when calling DrawRectangle. Experiment with LineJoin, and other properties of the Pen class.
This is very hard for a simple question that you posted. There are a lot of things that you need to take care of.
First I would suggest to make a class that will have a Rectangle property since you can't subclass Rectangle because it is a structure.
You will need to handle the drawing, that is the simplest task as mentioned in the other answers so I'm not going to be specific about that.
Since you have small squares that indicate that the rectangle can be resized, you will have to implement method that checks whether the mouse point is within the big rectangle or some of the small suqares. In this case you should change your cursor to indicate the possibility of resizing.
To handle moving (but not resizing) of the rectangle you will have either to make a new small square with the sign for moving in all directions or you will handle that using cursor when the mouse position is within the Big Rectangle.
The main problem is identifying what to change when resizing, you have two options:(1) to change Location and Size properties or to change X, Y, Width and (2)Height properties of the rectangle. For instance, when you are moving top-right corner you should change both Location and Size in first case or Y and Width is you are using second option.
When you move the mouse while it is clicked, you should watch out in which direction mouse moves. If you split the viewport in quadrants where the center of your rectangle is the center of the Decartes coordinate system, by identifying in which quadrant is the mouse you will know which corner (or edge) of the quadrant you need to move.
Each mouse move will have to call Invalidate() because you can't use Xor like in C++. Therefore, when your Rectangle is displayed, you should be in a special mode where everything that not moves (not changes, everything except Rectangle and selected control) should be drawn to the Bitmap that is used between two redraws and you should only draw what is moving.
As you can see, there is a lot of things that should be taken care of. You should start with this only after you are sure that you have already implemented other parts of your program.

How to make location of children controls in WinForms relative?

I have a custom control derived from Control which is dynamically added to the form. The control can have negative values in Location and is by default painted relative to the top left corner.
How can I get the control to have negative coordinates and painted relative to right bottom corner for example?
The question title and the question ask two different things.
For the title: yes, you can do relative placement, but you'll need to use nested layout panels, like TableLayoutPanel and FlowLayoutPanel. They should be able to do most, if not all, of what you want to do.
For the actual question:
Why?
No, you can't.
I'm not sure you can do it using Location property, w/o doing lot's of extra coding.
But (1) you can set it's "Anchor" property to Right and Bottom instead of Top and Left. Then, each time you resize the Form it will stay in the same spot relative to Right-Bottom corner of containing panel (the Form). Then (2) can set your Top-Left of Location to such values that it will be out of visible area... so Every time your Form (or Panel) is resized - Control will stay out of visible area.
Hopes it help.
You could do something like
Point relativePos = new Point(-10, -10);
control.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
control.Location = new Point(this.ClientSize.Width - control.Width + relativePos.X, this.ClientSize.Height - control.Height + relativePos.Y);
where relative pos is the position relative to the bottom right. The anchor makes sure it stays there on resize.
I made small class to manage position and size depends on container size :
http://www.codeproject.com/Tips/492814/Relative-design-components-on-WinForm

How do I position an ellipse on a Silverlight Grid?

I am creating a silverlight application which will allow you to click at two places on the screen and will draw an ellipse whose major axis starts and ends at the click locations. The clickable area is a Silverlight Grid control. Currently:
When you first click, I am:
Dropping a marker at the click
point.
Creating an ellipse and parenting it
to the Grid.
Creating and setting an
AngleTransform on the ellipse.
As you move the mouse, I am:
Calculating the distance to the
first click point.
Setting the Width of the ellipse to
this length.
Calculating the angle of a line to
the click point and the Grid's
X-Axis.
Setting the Ellipse's AngleTransform Angle to this angle.
So far, so good. The ellipse is displayed, and its length and angle of rotation follow the mouse as it moves.
However, the major axis of the ellipse is offset from the click point.
How do I position the Ellipse so its major axis starts at the click point and ends at the current mouse position?
The answer turned out to be:
Don't use System.Windows.Shapes.Ellipse. Instead use System.Windows.Shapes.Path and embed an EllipseGeometry in it.
Also set the Path.RenderTransform to a RotateTransform.
Don't set Width or Height or Stretch on the Path. Instead set the Center, RadiusX, and RadiusY of the EllipseGeometry.
Finally, set the RotateTransform.Angle to the angle of intersection of the Ellipse major-axis and the X-axis (the ArcTan of the major-axis slope). Also set RotateTransform.CenterX and CenterY to the EllipseGeometry Center.
If I had to guess (code would help), I would think that you could add padding from the difference of the beginning click point to the left side of the grid, which should help move it over by the offset.
May be it's a good idea to use Canvas instead of grid for your application, than you will be able to set up shapes coordianates directly.

Categories

Resources