Ok heres my problem. I have a form that when it is not maximised, its maximum size has to be the total height of the components inside the form. To achieve this, i use this:
private void resize_form(object sender, EventArgs e)
{
this.MaximumSize = new System.Drawing.Size(1000, this.panel4.Height + this.label2.Height + this.HeightMin);
}
That fires on the Resize event of the form. Because the component size is always changing it made sense to do this on a resize event. How ever if i want to maximise the form, the form just goes to the highest settings defined in this.MaximumSize. So i was wondering is there a way to tell when a form is going to be maximised and set its maximumsize to the screen boundarys before the form maximises.
If there is a better way to change the maximumsize value without resize event, that would also be great :)
You still need to use the resize event, but check the WindowState:
if (this.WindowState == FormWindowState.Maximized)
{
// Do your stuff
}
As yshuditelu points out you can set the minimum size property of your form too - which should, when coupled with judicious use of anchor values, mean that it can never shrink too far and when it does grow the components will move and/or grow as required.
I found the answer that suited me perfectly. A lil WndProc override :D (i love WndProc now)
protected override void WndProc(ref Message message)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MAXIMIZE = 0xF030;
switch (message.Msg)
{
case WM_SYSCOMMAND:
int command = message.WParam.ToInt32() & 0xfff0;
if (command == SC_MAXIMIZE)
{
this.maximize = true;
this.MaximumSize = new System.Drawing.Size(0, 0);
}
break;
}
base.WndProc(ref message);
}
private void resize_form(object sender, EventArgs e)
{
if (!maximize)
{
this.MaximumSize = new System.Drawing.Size(1000, this.panel4.Height + this.label2.Height + this.HeightMin);
}
}
Basically it sets this.maximize to true when it receives teh SC_MAXIMIZE message. The resize event will only set a new MaximumSize if this.maximize is set to false. Nifty xD
Are you sure you don't want to be setting the MinimumSize property? If you set the MinimumSize to the size of all the labels, then the form will never be smaller than that. But it can still grow to whatever size the user wants, so long as it is larger than the minimum.
Check out the System.Windows.Forms.Screen class. Get the screen from a relevant point (to handle the multi-mon case) and then get its resolution.
This should work in conjunction with the other comment about checking FormWindowState.Maximized.
If the user clicks in the upper bar, they can resize the window, so I use this:
private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Normal)
{
this.WindowState = FormWindowState.Maximized;
}
}
Related
I have created a text box, inside a PictureBox, on mouse click at run time. Now I want to resize it using mouse drag. Is there some simple way to do this ?
Here is the code I have so far:
public partial class Form1 : Form
{
public static TextBox PTB; //declaring text box to be created
public static bool textOption; //stores the state of button , i.e whether or not text box button is clicked before or not
public Form1()
{
InitializeComponent();
this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (textOption == true)//if user selected option to draw text box
{
MouseEventArgs eM = (MouseEventArgs)e; //create an instance of mouse event
PTB = new TextBox();//dynamically creating text box
PTB.Location = new System.Drawing.Point(eM.X, eM.Y);//settign position of textbox where mouse was clicked
PTB.Name = "textBox1";
PTB.Size = new System.Drawing.Size(100, 20);//size of text box
this.pictureBox1.Controls.Add(PTB);//adding the textbox to the picture box
}
}
Update
I'm sorry I have totally misread your question.
The reason is probably that you seem to be under the impression that Paint programs have TextBoxes sitting on their canvas. They don't. They draw text the same way as they draw lines or circles etc..
Also: Resizing the TextBox will not change the Font size, in case that's is what you want.
Finally: A TextBox will never be transparent, it will always sit on the PictureBox and look, well, like a TextBox. Not like anything in a Paint programm..
But: If you actually do want to resize the TextBox here are a few hints:
You need some way to show the user they are on the right spot by changing the cursor to the right icon
You need to store the mouse down point (attention: it will be inside the TextBox!) and keep track of the increments in the MouseMove. As long as the Button is down all rported e.Location will still be in the TextBox coordinates.
Use the increments (not the absolute values) to increase the size of the TextBox.
It is really hard to get the resizing right on the top and left sides. (Because it will involve moving at the same time), so better don't try!
Do include moving, which is easy and will suffice for all you need.
No, this is a good deal harder than increasing font size. 200-300 lines of code, the last time I did it..
But you may find another somewhat simpler answer; look for "Resize Control with Mouse winforms c#" on Google..
I leave the old answer in place, even if it not what you were looking for..
Old answer about changing font size while placing text:
It is not very hard but you need to get it right; it is basically the same as drawing a Rectangle
with a live preview. You need these things: four events, a Point or two, a Size and a font variable..
The events are:
MouseDown
MouseMove
MouseUp
Paint
You need to store a point for the placement (in the MouseDown event) and a size you update in the MouseMove.
From that size you can calculate the maximum Font size you can fit in the Rectangle.
On MouseUp you finalize things.
In the Paint event you draw string at the down Point with the current Font size.
In the MouseMove you call Invalidate on the PictureBox to trigger the Paint event.
in the MouseMouve you should check the Button to be the left one.
For extra good UI you can also check the keyboard for space and use it to move the DownPoint..
The Click event is rather useless, btw..
Here is a minimal code example to get you started:
Point mDown = Point.Empty;
float fSize = 12f;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Font font = new Font("Consolas", fSize))
e.Graphics.DrawString("Hello World", font, Brushes.Black, mDown);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mDown = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
fSize = Math.Abs(e.Y - mDown.Y) / 2f + 1;
pictureBox1.Invalidate();
}
I left out the MouseUp. Here you would store the final state (font, location..) of the drawn string somewhere or persist it by drawing into a Bitmap etc..
I also didn't do a full Rectangle calculation but determined the font size by simply scaling the y-movement down a little.. You could improve with a little pythagoras ;-)
The ability to resize a window is innate behavior, provided by the default window procedure built into Windows. All you have to do is give the control a resizable border. Everything else is for free, you'll get the correct cursor and dragging a corner or edge resizes the control.
using System;
using System.Windows.Forms;
class ResizeableTextBox : TextBox {
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.Style |= 0x840000; // Turn on WS_BORDER + WS_THICKFRAME
return cp;
}
}
}
This sample will create the TextBox on the MouseDown event and start resizing, the final size of the TextBox will be where the mouse button is released on the MouseUp event. It will let you create multiple textboxes as well.
I realize this might not be exactly what you want but it might be a start.
private int _textBoxCounter;
private TextBox _textBoxCurrentResizing;
public Form1()
{
InitializeComponent();
pictureBox1.MouseDown += PictureBox1OnMouseDown;
pictureBox1.MouseUp += PictureBox1OnMouseUp;
pictureBox1.MouseMove += PictureBox1OnMouseMove;
}
public Point RelativeMousePosition { get { return PointToClient(MousePosition); } }
private void PictureBox1OnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
ResizeTextBox();
}
private void PictureBox1OnMouseUp(object sender, MouseEventArgs mouseEventArgs)
{
EndResizeTextBox();
}
private void PictureBox1OnMouseDown(object sender, MouseEventArgs mouseEventArgs)
{
var tb = CreateTextBox();
StartResizeTextBox(tb);
}
private TextBox CreateTextBox()
{
var tb = new TextBox
{
Location = RelativeMousePosition,
Size = new Size(100, 20),
Multiline = true,
Name = "textBox" + _textBoxCounter++,
};
pictureBox1.Controls.Add(tb);
return tb;
}
private void StartResizeTextBox(TextBox tb)
{
_textBoxCurrentResizing = tb;
}
private void ResizeTextBox()
{
if (_textBoxCurrentResizing == null) return;
var width = Math.Abs(_textBoxCurrentResizing.Left - RelativeMousePosition.X);
var height = Math.Abs(_textBoxCurrentResizing.Top - RelativeMousePosition.Y);
_textBoxCurrentResizing.Size = new Size(width, height);
}
private void EndResizeTextBox()
{
_textBoxCurrentResizing = null;
}
I have a form acting as a sidebar, that will always be locked in position, and width. However, if I were to resize the MDI Container, this form should also grow to fit the Parent form length-ways.
For example, if I were to use a method in the Parent form like so:
private void ParentForm_SizeChanged(object sender, EventArgs e)
{
FormWindowState LastWindowState = FormWindowState.Normal;
if (this.WindowState != LastWindowState)
{
if (this.WindowState == FormWindowState.Maximized)
ResizeChildForm(this);
}
}
And then in the Child form, if I have the property Locked = true; will I have to disable that, resize the form, then enable that again? I.e.
private void ResizeChildForm(ParentForm)
{
this.Locked = false;
//resize form
this.Locked = true;
}
Or can I just change the size of the form without having to change that property?
To answer your question,
can I just change the size of the form without having to change that property?
Yes you can, see this link for more details.
Note from the article :
Locking controls prevents them from being dragged to a new size or location on the design surface. However, you can still change the size or location of controls by means of the Properties window or in code.
I am writing a screensaver program in C#. And I want it to do the following:
Start with a text. After about 3 seconds or more, hide the text and show an image. After the next 3 seconds, hide the image show the text and keep going round the loop until the user does something that exits the screensaver.
What I have done:
I started with a simple textlabel and a timer control. I was able to get the textlabel change positions on screen after every 3 seconds. I updated my code to include a picturebox, and in my timer_tick method, I inserted an if-else statement to check, when the method is called,
if the textlabel is shown, hide it and show the picturebox.
else if the picturebox is shown, hide it and show the textbox. Code is shown below:
private void Form1_Load(object sender, EventArgs e)
{
Cursor.Hide();
TopMost = true;
moveTimer.Interval = 3000;
moveTimer.Tick += new EventHandler(moveTimer_Tick);
moveTimer.Start();
}
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Enabled == true)
{
pictureBox1.Hide();
textLabel.Show();
}
if (textLabel.Enabled == true)
{
textLabel.Hide();
pictureBox1.Show();
}
}
Here's the problem:
WHen I run the screensaver program, the screen starts with the text, changes to the picture after 3 seconds and stops there.
What do I do to get it moving in a continous loop, showing/hiding the textlabel or picturebox?
Have I implemented this in the right way?
Please clear and concise explanations/answers will be highly appreciated.
Thanks!
Perhaps you could keep the state in a variable that you can switch
private bool state = false;
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (state)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
state = !state;
}
How about something like this?
Enabled says whether the object can receive input.
Visible is what says if its visible or not.
You see it change once and only once because all the objects are enabled. The first if succeeds, hiding the picture and showing the text. But then the second if also succeeds, showing the picture and hiding the text. Since this is all in one event callback, you never see the first if happen, because the second overrides it.
As you're realizing in the comments, the answer is to not check enabled. Instead, check Visible. Make sure to use an else as well, otherwise you may still get the same issue of both being true.
private void moveTimer_Tick(object sender, System.EventArgs e)
{
//Move text to new Location
//textLabel.Left = rand.Next(Math.Max(1, Bounds.Width - textLabel.Width));
//textLabel.Top = rand.Next(Math.Max(1, Bounds.Height - textLabel.Height));
if (pictureBox1.Visible == true)
{
pictureBox1.Hide();
textLabel.Show();
}
else
{
textLabel.Hide();
pictureBox1.Show();
}
}
I have an application. If the application is not being used for a certain amount if time, it should hide. When application is hidden and we mouse-over the icon, it should be restored.
How can I do this? Thanks in advance.
You have to define a timer in your application that will count the time when mouse is not over the form/window. Then just hide your application.
Download WPF NotifyIcon
And handle MouseOver event, that will show Form/Window
EDIT:
If you do not need to minimize application to tray and hide window keeping it on desktop -> use the same algorithm, but do not hide the window, just set transparency to 0% or 10%. When mouse is over - set transparency to 100%.
Like JesseJames said, use a timer to measure the inactive time of the application and hide it after an amount of time. Re-activate it when the mouse is hovered over the NotifyIcon. Here's a sample WindowsForms solution that does the job:
private Timer _timer;
private int _ticks;
public Form1()
{
_timer = new Timer { Interval = 1000, Enabled = true };
_timer.Tick += TimerTick;
Activated += Form1_Activated;
MouseMove += Form1_MouseMove;
//notifyIcon1 is an icon set through the designer
notifyIcon1.MouseMove += NotifyIcon1MouseMove;
}
protected void TimerTick(object sender, EventArgs e)
{
//After 5 seconds the app will be hidden
if (_ticks++ == 5)
{
WindowState = FormWindowState.Minimized;
Hide();
_timer.Stop();
_ticks = 0;
}
}
protected void NotifyIcon1MouseMove(object sender, MouseEventArgs e)
{
WindowState = FormWindowState.Normal;
Show();
_ticks = 0;
_timer.Start();
}
protected void Form1_MouseMove(object sender, MouseEventArgs e)
{
_ticks = 0;
}
Perhaps there might exist a cleaner solution, I don't know, but it gets you on the way. Same principle will go for WPF, only the code will be slightly different. Hope this helps!
To see if the user has made any input you can use a similar approach like this one. To get your application visible again you need a way to get the global mouse and maybe keyboard input, to do this you can use hooks, you can find one solution for that here. And if the hook is triggered it really just depends on what kind of UI you are using, but calling specific hide or show methods should be suffice.
I was building a simple form with one simple effect- opacity reduced when mouse is not over the form, and form becomes opaque when mouse is over it. I am currently encountering couple of difficulties:-
Firstly, I did this-
this.MouseHover += new EventHandler(Form1_MouseHover);
this.MouseLeave += new EventHandler(Form1_MouseLeave);
But I had 1 richtextbox in form too, and as mouse went over it, the form lost opacity again. I had to add this too:-
richTextBox1.MouseHover+=new EventHandler(Form1_MouseHover);
richTextBox1.MouseLeave+=new EventHandler(Form1_MouseLeave);
wondering if there was any better way,because there is still some gap between richtextbox and form boundaries, and form is losing opacity when mouse cursor goes there.
If the mouse is NOT over the form (suppose initially), the form is less opaque. Now, I want form to become opaque as soon as mouse goes over it, but it only happens when mouse movement over form stops completely. If I keep moving mouse over the form, it does not become opaque. Is this a problem with the way events are stored in message queue and all that or will I be able to do something, because I have seen applications with the effect I am trying to implement.
The MouseEnter/Leave events are too unreliable to do this. Best thing to do is just use a Timer that checks if the mouse is still inside the window. Drop a Timer on the form and make the code look like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.Opacity = 0.99;
timer1.Interval = 200;
timer1.Enabled = true;
timer1.Tick += timer1_Tick;
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
timer1_Tick(this, e);
}
private void timer1_Tick(object sender, EventArgs e) {
this.Opacity = this.Bounds.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
}
}
Btw: avoid increasing the Opacity to 1.0, that forces the native window to be recreated and that can have a lot of side-effects. Using 0.99 is best.
I might be wrong, but why would you use MouseHover event? MouseHover detects when the mouse stop moving on the form and is usually used to show Tooltips.
The event you are looking for is MouseEnter which is the opposite of MouseLeave and detects when the mouse enters the client rect of a window.
In the Leave event, just check if the cursor position is in the window client rect to know if it did actually leave the form or if it is just on top of child control.
Ofc if you use a region, you'll have to adapt the code.
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1;
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
if (!this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))
{
this.Opacity = 0.5;
}
}
Add a timer control then use below in timer's tick event. Above answers won't work if you have custom/user controls in your form. So have to use ClientRectangle
this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1.0;
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
this.Opacity = 0.8;
}