How to determine the height of an InputBox? - c#

I'm using the InputBox from the VB .dll. When I display it, I want to put it in a particular place relative to the controls it will have an impact on (out of their way). So I have this pseudocode for showing the InputBox ("selectionStart" is a Point assigned to on MouseDown):
int HeightOfInputBox = ? <- What is this value?
int XPos = selectionStart.X;
int YPos = selectionStart.Y - HeightOfInputBox;
Interaction.InputBox("Prompt", "Title", "DefaultResponse", XPos, YPos);
My question is: What is the height of an InputBox?

You do not have access to the object to get the Height or Width information. The only properties available are what you set when you initialize it. If you need the Height you will need to roll your own. This CodeProject article is an example on how to, you could just add another intializer to set the Width and Height of the InputBox.
i.e. InputBox("Prompt", "Title", "DefaultResponse", XPos, YPos, Width, Height);

you can use
Me.ActiveControl
for the current control

Related

How can i calculate the distance from the top of pictureBox1 and almost the top of form1?

I have a label with text inside i can change the label size or the label font size each time and check many times but maybe there is a way to calculate it:
label18.Text = "מכם מזג האוויר איננו פעיל כרגע";
This is how i see the text now:
The text in red is in hebrew this is the text i want to change it's size and also to put it in the middle according to the picturebox1 top not on the left like it is now.
And i did a black circle just to show what i mean by " the distance from the top of pictureBox1 and almost the top of form1 ".
I mean this gray area from the above the pictureBox1 and the form1 white area on the top only this gray area i want to make the text in this height and in the middle.
How can i calculate this two values ?
I tried this but it's not in the exact middle:
SizeF size = label18.CreateGraphics().MeasureString(label18.Text, label18.Font);
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = pictureBox1.Top - 20;
You don't need graphics or to measure anything. Just set in designer text align = middlecenter and autosize = true
label18.Location = new Point(pictureBox1.Location.X + (pictureBox1.Width / 2 - label18.Width / 2,
pictureBox1.Location.Y - label18.Height);
To center a label you need it get it actual size, then to center it using another control use some simple math to get the coordinate for the control (see below Example 1). I don't know what control the grey bar is but you could center in that by using the size.Width property and doing the same type of calculation.
If you want to fill the grey bar I have added Example 2.
Example 1:
private void CenterLabel()
{
//get the size of the text (you could do this before hand if needed)
SizeF size = label18.CreateGraphics().MeasureString(label18.Text, label18.Font);
//center over picture box control and slightly above
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = pictureBox1.Top - 20;
}
Example 2
private void CenterLabel()
{
int fontHeightPixels = (int)(greyBar.Height * .85);
Font font = new System.Drawing.Font("Arial", fontHeightPixels, FontStyle.Regular, GraphicsUnit.Pixel);
string text = "I am centered";
//get the size of the text (you could do this before hand if needed)
SizeF size = label18.CreateGraphics().MeasureString(text, font);
label18.Font = font;
label18.Text = text;
//center over picture box control and slightly above
label18.Left = (pictureBox1.Width / 2) - (((int)size.Width) / 2) + pictureBox1.Left;
label18.Top = (greyBar.Height / 2) - (((int)size.Height) / 2) + greyBar.Top;
}
This is relatively simple with Windows forms:
Dock your label to the top of the form by setting the appropriate property in the Forms designer. The property you want to set is Dock and it should be set to Top.
Change the label's AutoSize property to false.
Change the label's height as desired.
Change the label's TextAlign property to MiddleCentre.
That should do it.
There's more then one way to achieve this goal.
I would suggest the following:
First calculate the width of the picturebox (picturebox.Width)
Find the coordinates on the form where the picturebox resides (picturebox.Location) property of the picturebox)
Then you change the location of your label control --> to Label.Location.X = (picturebox.Width /2) and Label.Location.Y = picturebox.Location.Y ==> now you have the label correctly placed .
Next Set the Height of the Label Control to the Top(distance between the edge of the form and picturebox) value of the Picturebox.
No visual studion from where i am typing so cannot do full code example.
You're done.

when i try to move my picture with.Bottom keep getting error but i can move it with.Left and .Top

in Microsoft windows visual c# windows form application I keep getting this error message.
Error 1 Property or indexer 'System.Windows.Forms.Control.Bottom' cannot be assigned to -- it is read only
I can move the image with a int Control.Left or a Top but not a Bottom or Right what wrong with it
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Bottom += 1;
}
Bottom property is read only (as Right is).
You can however manipulate it's value indirectly by changing values of Top or Size properties.
From Control.Bottom Property
The value of this property is equal to the sum of the Top property
value, and the Height property value.
The Bottom property is a read-only property. You can manipulate this
property value by changing the value of the Top or Height properties
or calling the SetBounds, SetBoundsCore, UpdateBounds, or
SetClientSizeCore methods.
Presumably your picture is a square, meaning you should easily be able to calculate the required Top and Left positions from the Bottom and Right you would like, together with the height and width of the picture.
Do that instead, and just use Top and Left.
As error says, you cannot assign Bottom property - its calculated based on control size and location:
public int Bottom
{
get { return this.y + this.height; }
}
And its for reading only. On the other hand, Left and Top will change bounds of control by changing it's x or y position:
public int Left
{
get { return this.x; }
set
{
SetBounds(value, this.y, this.width, this.height, BoundsSpecified.X);
}
}
[Read my Blog Techhowdy][1]
// For right
pictureBox1.Top = ((Control)sender).Top;
pictureBox1.Height = ((Control)sender).Height;
// For bottom
pictureBox1.Left = ((Control)sender).Left;
pictureBox1.Width= ((Control)sender).Width;
// For top
pictureBox1.Top= ((Control)sender).Top;
pictureBox1.Width = ((Control)sender).Width;
// Casting it to Control will solve your problem - use Left as it can be manupilated
[1]: http://techhowdy.com

New area not repaints when user-drawn control size is increased

I think I'm missing something trivial here. I derived simple control directly from Control. I'm overriding OnPaint and painting the rectangle (e.Graphics.DrawRectangle)and a text inside it (e.Graphics.DrawString). I did not override any other members.
It paints itself well when the control is resized to the smaller size, but when it gets resized to the larger size, new area is not repainted properly. As soon as I resize it to the smaller size again, even if by one pixel, everything repaints correctly.
OnPaint gets called properly (with appropriate PaintEventArgs.ClipRectangle set correctly to new area), but the new area is not painted (artifacts appear) anyway.
What am I missing?
EDIT:
Code:
protected override void OnPaint(PaintEventArgs e)
{
// Adjust control's height based on current width, to fit current text:
base.Height = _GetFittingHeight(e.Graphics, base.Width);
// Draw frame (if available):
if (FrameThickness != 0)
{
e.Graphics.DrawRectangle(new Pen(FrameColor, FrameThickness),
FrameThickness / 2, FrameThickness / 2, base.Width - FrameThickness, base.Height - FrameThickness);
}
// Draw string:
e.Graphics.DrawString(base.Text, base.Font, new SolidBrush(base.ForeColor), new RectangleF(0, 0, base.Width, base.Height));
}
private int _GetFittingHeight(Graphics graphics, int width)
{
return (int)Math.Ceiling(graphics.MeasureString(base.Text, base.Font, width).Height);
}
Try adding this in your constructor:
public MyControl() {
this.ResizeRedraw = true;
this.DoubleBuffered = true;
}
and in your paint event, clear the previous drawing:
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.Clear(SystemColors.Control);
// yada-yada-yada
}
While ResizeRedraw will work, it forces the entire control to repaint for every resize event, rather than only painting the area that was revealed by the resize. This may or may not be desirable.
The problem the OP was having is caused by the fact that the old rectangle does not get invalidated; only the revealed area gets repainted, and old graphics stay where they were. To correct this, detect whether the size of your rectangle has increased vertically or horizontally, and invalidate the appropriate edge of the rectangle.
How you would specifically go about this would depend on your implementation. You would need to have something that erases the old rectangle edge and you would have to call Invalidate passing an area containing the old rectangle edge. It may be somewhat complicated to get it to work properly, depending what you're doing, and using ResizeRedraw after all may be much simpler if the performance difference is negligible.
Just for example, here is something you can do for this problem when drawing a border.
// member variable; should set to initial size in constructor
// (side note: should try to remember to give your controls a default non-zero size)
Size mLastSize;
int borderSize = 1; // some border size
...
// then put something like this in the resize event of your control
var diff = Size - mLastSize;
var wider = diff.Width > 0;
var taller = diff.Height > 0;
if (wider)
Invalidate(new Rectangle(
mLastSize.Width - borderSize, // x; some distance into the old area (here border)
0, // y; whole height since wider
borderSize, // width; size of the area (here border)
Height // height; all of it since wider
));
if (taller)
Invalidate(new Rectangle(
0, // x; whole width since taller
mLastSize.Height - borderSize, // y; some distance into the old area
Width, // width; all of it since taller
borderSize // height; size of the area (here border)
));
mLastSize = Size;

How to determine the screen width/height using C#

I want to set the width & height of a Window dynamically based on the user screens maximum width/height. How can I determine this programmatically?
For the primary screen:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
(Note that there are also some other primary screen related properties which depend on various factors, Full* & Maximised*)
Virtual screen:
SystemParameters.VirtualScreenWidth
SystemParameters.VirtualScreenHeight
If you want the specific dimensions of the monitor your program is running on (if someone is running more than one monitor) you could also use:
var helper = new WindowInteropHelper(this); //this being the wpf form
var currentScreen = Screen.FromHandle(helper.Handle);
This will return a screen object referencing the monitor the program is running on. From there you can use the currentScreen.Bounds.Width / Height property (for the full size) or the currentScreen.WorkingArea.Width / Height (minus task bar, etc.) depending on what you want.
use Screen Object
Screen.PrimaryScreen.Bounds.Width
I couldn't use any of the solutions above under .NET 4.0.30319.42000 with Windows 10 Enterprise when calling it from the Ranorex Studio 8.0.1+git.8a3e1a6f, so I used the line
using WinForms = System.Windows.Forms;
[…]
SetWindowPos(processes[0].MainWindowHandle,
0,
y,
x,
WinForms.SystemInformation.PrimaryMonitorSize.Width,
WinForms.SystemInformation.PrimaryMonitorSize.Height,
SWP.SHOWWINDOW);
You can use the SizeChanged event
SizeChanged="MyWindow_SizeChanged"
Then in your event handler,
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.MinWidth > 0 && this.MinHeight > 0)
{
double heightScaleFactor = e.NewSize.Height / this.MinHeight;
double widthScaleFactor = e.NewSize.Width / this.MinWidth;
mainGrid.LayoutTransform = new ScaleTransform(heightScaleFactor, widthScaleFactor);
}
}
where MainGrid is a container for all the contents in MyWindow.
You can get the screen height and width:
int height = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Height;
int width = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Width;
Then set the Window's Height and Width properties to those in the Initialization.
this.Height = height;
this.Width = width;
Works to get the screen's height and width in WinForms or in ASP .NET. No muss, no fuss, except you'll need to reference the System.Windows.Forms assembly in your project if it's not a WinForm project.

Fixing the position of a form

I am starting a winform application[.NET 3.5, C#], where in the the main form of the application starts at a particular specified location. Am calling the following code in the constructor for this
private void SetFormPosition()
{
this.StartPosition = FormStartPosition.Manual;
this.Left = Screen.PrimaryScreen.WorkingArea.Right - this.Width;
this.Top = Screen.PrimaryScreen.WorkingArea.Bottom - this.Height;
}
After the application starts, I would like to keep the location of the form fixed throughout the application lifetime.
Perhaps, I could 'tap' the Location event changed but am not sure if that would be very elegant.
Please suggest.
Thanks.
I agree with others that you probably shouldn't be doing this, but if you must, read on.
You can override the SetBoundsCore method and prevent any movement. We use this to prevent vertical resizing on some UserControl implementations (such as those that contain a ComboBox or other fixed height control), but it is also responsible for the location changing.
The following should get you started:
protected override void SetBoundsCore(
int x, int y, int width, int height, BoundsSpecified specified)
{
x = this.Location.X;
y = this.Location.Y;
//...etc...
base.SetBoundsCore(x, y, width, height, specified);
}
You could set the FormBorderStyle to None. This has the added benefit of removing the bar at the top of the window that would give users a false sense that they should be able to move the window.
Just change this
Location = new Point(this.Width,this.Height);

Categories