I am creating a CustomButton control for my application. Now, What I want to do that when the mouse goes on the button it should show glow effect and when mouse leave it should get back to normal. But the glow effect should not displayed immediately. It should display with animation. just like Chrome Browser Tab Page. I have tried this logic in the button control.
This is my logic. But, I think this is not a proper way. please suggest proper way to get glow effect.
private void ShowGlow()
{
for (int i = 0; i<50; i+= 5)
{
Sleep(100);
Graphics g = this.CreateGraphics();
Color color = Color.FromArgb(i, 150,150,25);
g.FillRectangle(new SolidBrush(color), this.ClientRectangle);
}
}
Additional Details
Visual Studio 2005, Windows XP, Windows Form Controls
I suggest you a simpler method.
Create two images, with glow effect and without.
And use this code.
On MouseEnter:
private void MyButton_MouseEnter(object sender, EventArgs e)
{
MyButton.BackgroundImage = Properties.Resources.WithGlow;
}
On MouseLeave:
private void MyButton_MouseLeave(object sender, EventArgs e)
{
MyButton.BackgroundImage = Properties.Resources.WithoutGlow;
}
This is what I usually do in my projects.
Here is some code that uses timers and overrides the OnPaint method. It skips by 10 instead of 1 because I was afraid you wouldn't see the effect fast enough otherwise. The Timer interval is in milliseconds and was set to 100 because that was what you were using in your original example for sleep. If you need the effect to work faster, you can reduce the interval. If it should be slower, you can increase the interval, or decrease how much you increment alpha with each tick.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LicensePlate
{
/// <summary>
/// The GlowButton class
/// </summary>
public class GlowButton : Button
{
#region Fields
Timer timer;
private int alpha;
Color color;
#endregion
#region Events
#endregion
#region Constructor
/// <summary>
/// Creates a new instance of the GlowButton class.
/// </summary>
public GlowButton()
{
timer = new Timer();
timer.Interval = 100;
timer.Tick += timer_Tick;
}
#endregion
#region Methods
/// <summary>
/// Only used if you need something else to trigger the glow process
/// </summary>
private void ShowGlow()
{
timer.Start();
}
/// <summary>
/// Start the timer and reset glow if the mouse enters
/// </summary>
/// <param name="e"></param>
protected override void OnMouseEnter(EventArgs e)
{
timer.Start();
alpha = 0;
}
/// <summary>
/// Reset the glow when the mouse leaves
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
timer.Stop();
alpha = 0;
color = BackColor;
Invalidate();
}
/// <summary>
/// Override paint so that it uses your glow regardless of when it is instructed to draw
/// </summary>
/// <param name="pevent"></param>
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
if (alpha > 0)
{
using (Brush b = new SolidBrush(color))
{
pevent.Graphics.FillRectangle(b, this.ClientRectangle);
}
}
//base.OnPaint(pevent);
}
/// <summary>
/// Use a timer tick to set the color and increment alpha
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void timer_Tick(object sender, EventArgs e)
{
alpha+=10;
color = Color.FromArgb(alpha, 150, 150, 25);
if (alpha > 50) {
timer.Stop();
}
Invalidate();
}
#endregion
}
}
Related
I want a code that makes 'Form 2' close after 30 minutes and 'Form 1' to show up.
private void button1_Click_1(object sender, EventArgs e)
MessageBox.Show("Thank you for using Crystal X!", "Success");
this.Hide();
CrystalX main = new CrystalX();
main.Show();
(Code to wait 30 minutes)
this.Hide();
Form1 main = new Form1();
main.Show();
One method is to setup a Timer and Action.
Action in your form
public void FormWork()
{
this.Hide();
Form1 main = new Form1();
main.Show();
TimerHelper.Stop();
}
In the same form, your altered Click event
private void button1_Click_1(object sender, EventArgs e)
{
MessageBox.Show("Thank you for using Crystal X!", "Success");
this.Hide();
CrystalX main = new CrystalX();
main.Show();
TimerHelper.Start(FormWork);
}
Create a new class named ActionContainer in the same project.
public class ActionContainer
{
/// <summary>
/// Action to perform
/// </summary>
public Action Action { get; set; } = () => { };
}
Now for the worker class named TimerHelper. Note the event Message is completely optional, used more so to see when code is executed. Change the namespace to your project's namespace.
using System;
using System.Threading;
using Timer = System.Threading.Timer;
namespace WorkingWithTimer.Classes
{
public class TimerHelper
{
/// <summary>
/// How long between intervals, currently 30 minutes
/// </summary>
private static int _dueTime = 1000 * 60 * 30;
private static Timer _workTimer;
public static ActionContainer ActionContainer;
/// <summary>
/// Text to display to listener
/// </summary>
/// <param name="message">text</param>
public delegate void MessageHandler(string message);
/// <summary>
/// Optional event
/// </summary>
public static event MessageHandler Message;
/// <summary>
/// Flag to determine if timer should initialize
/// </summary>
public static bool ShouldRun { get; set; } = true;
/// <summary>
/// Default initializer
/// </summary>
private static void Initialize()
{
if (!ShouldRun) return;
_workTimer = new Timer(Dispatcher);
_workTimer.Change(_dueTime, Timeout.Infinite);
}
/// <summary>
/// Initialize with time to delay before triggering <see cref="Worker"/>
/// </summary>
/// <param name="dueTime"></param>
private static void Initialize(int dueTime)
{
if (!ShouldRun) return;
_dueTime = dueTime;
_workTimer = new Timer(Dispatcher);
_workTimer.Change(_dueTime, Timeout.Infinite);
}
/// <summary>
/// Trigger work, restart timer
/// </summary>
/// <param name="e"></param>
private static void Dispatcher(object e)
{
Worker();
_workTimer.Dispose();
Initialize();
}
/// <summary>
/// Start timer without an <see cref="Action"/>
/// </summary>
public static void Start()
{
Initialize();
Message?.Invoke("Started");
}
/// <summary>
/// Start timer with an <see cref="Action"/>
/// </summary>
public static void Start(Action action)
{
ActionContainer = new ActionContainer();
ActionContainer.Action += action;
Initialize();
Message?.Invoke("Started");
}
/// <summary>
/// Stop timer
/// </summary>
public static void Stop()
{
_workTimer.Dispose();
Message?.Invoke("Stopped");
}
/// <summary>
/// If <see cref="ActionContainer"/> is not null trigger action
/// else alter listeners it's time to perform work in caller
/// </summary>
private static void Worker()
{
Message?.Invoke("Performing work");
ActionContainer?.Action();
}
}
}
Another example, simply moving the second form and timer declarations out to form/class level in the first form:
private CrystalX main = null;
private System.Windows.Forms.Timer tmr = null;
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
if (main == null || main.IsDisposed)
{
main = new CrystalX();
main.FormClosed += Main_FormClosed;
}
if (tmr == null)
{
tmr = new System.Windows.Forms.Timer();
tmr.Tick += Tmr_Tick;
tmr.Interval = (int)TimeSpan.FromMinutes(30).TotalMilliseconds;
}
main.Show();
tmr.Start();
}
private void Main_FormClosed(object sender, FormClosedEventArgs e)
{
if (tmr != null && tmr.Enabled)
{
tmr.Stop();
}
this.Show();
main = null;
}
private void Tmr_Tick(object sender, EventArgs e)
{
if (main != null && !main.IsDisposed)
{
main.Close();
}
}
I've built a simple application that links to the url of image searches pertaining to the content of the listbox to the right of the browser window as follows:
https://1drv.ms/i/s!Ar02lrNB2lmbm0g7RF3RY6-T6NHz
I've accomplished this with several if statements that refer to the index of my list box, what I am hoping for is a more eloquent solution to this problem. As of now each new search term must be hard coded and refers to the same image search, is there by chance a way that the text in the listbox could be read and an image search performed instead of the solution I have? I mean it works but there has to be a better way.
public partial class frmCatSearch : Form
{
public frmCatSearch()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Event Handler for the button
// Pop up a message box with the current time/date
MessageBox.Show(DateTime.Now.ToString());
}
/// <summary>
/// Navigates to a google image search depending on the selected
/// listbox item.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (lblArtimus.SelectedIndex == 0)
{
artimusBrowser.Navigate("https://www.google.com/search");
}
if (lblArtimus.SelectedIndex == 1)
{
artimusBrowser.Navigate("https://www.google.com/search");
}
if (lblArtimus.SelectedIndex == 2)
{
artimusBrowser.Navigate("https://www.google.com/search");
}
//else
//{
// artimusBrowser.Navigate("https://images.google.com/?gws_rd=ssl");
//}
}
//Code purposefully omitted
/// <summary>
/// Loads objects into listbox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frm_Load(object sender, EventArgs e)
{
//Add some cats
lblArtimus.Items.Add("Alley Cat");
lblArtimus.Items.Add("American Bobtail");
lblArtimus.Items.Add("Burmilla");
lblArtimus.Items.Add("Cornish Rex");
lblArtimus.Items.Add("Devon Rex");
lblArtimus.Items.Add("Maine Coon");
lblArtimus.Items.Add("Chesire");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
Are you just trying to get the text from the selected item? If so, will this do:
string searchText = this.listBox1.SelectedItem.ToString();
Then just search for the value of searchText.
I may be missing what you're trying to achieve here though.
Ok so I am testing with adding a picturebox to my winform app. I am finally asking here, because when ever I look up how to do this I don't see anything different than what I am doing. Here is the code:
namespace AddPanel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PictureBox pictureBox1 = new PictureBox();
pictureBox1.ImageLocation = #"C:\Users\xoswaldr\Desktop\OrangeLogo.jpg";
pictureBox1.Location = new System.Drawing.Point(20, 40);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new System.Drawing.Size(100, 50);
pictureBox1.BackColor = Color.Black;
this.Controls.Add(pictureBox1);
}
}
}
That is the entire code, because I am just trying to test adding a picturebox for something else I'm working on. What I am trying to do with this is when I run the program it puts the picturebox in the form, but that doesn't happen. The form is just blank.
-----EDIT------------
Here is the Form1.Designer.cs code
namespace AddPanel
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(690, 381);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
}
}
and here is the Program.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace AddPanel
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Is there something in the designer that is blocking it or something that I haven't added?
Since your code looks correct, is it possible there is another control covering the picture box?
Try bringing it to the Front:
private void Form1_Load(object sender, EventArgs e)
{
var pictureBox1 = new PictureBox
{
BackColor = Color.Black,
ImageLocation = #"C:\Users\xoswaldr\Desktop\OrangeLogo.jpg",
Location = new Point(20, 40),
Name = "pictureBox1",
Size = new Size(100, 50)
};
this.Controls.Add(pictureBox1);
pictureBox1.BringToFront();
}
The picture may not be completely displayed, just set the SizeMode to have a try:
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom
I'm new to C# and I've attempted many of the solutions here on StackExchange and I've had no luck in trying to set up a control or the entire form for that matter to left click and drag the entire window. I'm working with a frameless window in visual studio 12. The closest I've come to moving the window is moving a single control with the pastebin component(last response) from this-
How do I make mousedrag inside Panel move form window?
I could only get the panel itself to move with that component.
I've tried most of the approaches but I seem get lost where I am to customize it to my own needs. I've tried WndProc override but it didn't do anything when I attempted to move the form window.
I have two panels I want to be able to drag the window with DragPanel and DragPanel2.
Here is my most recent failed approach trying to use the whole form.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InsideMover _dragger = new InsideMover();
_dragger.ControlToMove = this.DragPanel;
}
private void close_Click(object sender, EventArgs e)
{
Close();
}
}
public class InsideMover : Component
{
/// <summary>
/// Required designer variable.
/// </summary>
private Container components = null;
public InsideMover(IContainer container)
{
///
/// Required for Windows.Forms Class Composition Designer support
///
container.Add(this);
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
public InsideMover()
{
///
/// Required for Windows.Forms Class Composition Designer support
///
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
public Control ControlToMove
{
set
{
if (_parent != null)
{
// odkvaci prijasnje evente
_parent.MouseDown -= new MouseEventHandler(_parent_MouseDown);
_parent.MouseMove -= new MouseEventHandler(_parent_MouseMove);
_parent.MouseUp -= new MouseEventHandler(_parent_MouseUp);
_parent.DoubleClick -= new EventHandler(_parent_DoubleClick);
}
_parent = value;
if (value != null)
{
// zakači se na evente od containera koji ti trebaju
_parent.MouseDown += new MouseEventHandler(_parent_MouseDown);
_parent.MouseMove += new MouseEventHandler(_parent_MouseMove);
_parent.MouseUp += new MouseEventHandler(_parent_MouseUp);
_parent.DoubleClick += new EventHandler(_parent_DoubleClick);
}
}
get
{
return _parent;
}
}
Control _parent;
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
int _lastMouseX;
int _lastMouseY;
bool _moving;
public void StartMouseDown(MouseEventArgs e)
{
_parent_MouseDown(null, e);
}
private void _parent_MouseDown(object sender, MouseEventArgs e)
{
_lastMouseX = e.X;
_lastMouseY = e.Y;
_moving = true;
}
private void _parent_MouseMove(object sender, MouseEventArgs e)
{
if (_moving)
{
Point newLocation = _parent.Location;
newLocation.X += e.X - _lastMouseX;
newLocation.Y += e.Y - _lastMouseY;
_parent.Location = newLocation;
}
}
private void _parent_MouseUp(object sender, MouseEventArgs e)
{
_moving = false;
}
private void _parent_DoubleClick(object sender, EventArgs e)
{
if (_parent is Form)
{
Form f = (Form)_parent;
if (f.WindowState == FormWindowState.Normal)
{
f.WindowState = FormWindowState.Maximized;
}
else
{
f.WindowState = FormWindowState.Normal;
}
}
}
}
}
How can I set the panels to left click drag the window?
I've tried all of the methods at the post above and the WndProc method here:
Drag borderless windows form by mouse
If you follow the answer in the link you've posted, it is using the mousemove event, whereas judging by the code you've posted, you're using the mousedown event. The mouse down event is only called once when you press a mouse button, it is not called again if you move the mouse while you keep pressing the button. Whereas the mousemove event is called whenever your pointer moves. So your best bet would be to change your mousedown event with the mousemove event i.e.
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
if that doesn't work, you can do something like this in the mousemove event, first create a Point 'prevpoint' and an offset point in the form.
Point prevpoint=new Point(0,0);
Point offset=new Point(0,0);
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
offset.X=e.X-prevpoint.X;
offset.Y=e.Y-prevpoint.Y;
prevpoint.X=e.X;
prevpoint.Y=e.Y;
this.Location = new Point(this.Location.X + offset.X, this.Location.Y + offset.Y);
}
}
I have not tested the above code but that will hopefully give you the basic idea.
I have img1, and img2 in my resources. I have easily set btn.backgroundImage as img1 in btn properties. Images paths are: c:\Project\Resources...
Now I don't know how to set btn.backgroundImage to be img2, I want to do it on event "MouseEnter". So I would apreciate complete code, because I am pretty green about this...
I apreciate any given idea...
In the case of winforms:
If you include the images to your resources you can do it like this, very simple and straight forward:
public Form1()
{
InitializeComponent();
button1.MouseEnter += new EventHandler(button1_MouseEnter);
button1.MouseLeave += new EventHandler(button1_MouseLeave);
}
void button1_MouseLeave(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img1));
}
void button1_MouseEnter(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
I would not recommend hardcoding image paths.
As you have altered your question ...
There is no (on)MouseOver in winforms afaik, there are MouseHover and MouseMove events, but if you change image on those, it will not change back, so the MouseEnter + MouseLeave are what you are looking for I think. Anyway, changing the image on Hover or Move :
in the constructor:
button1.MouseHover += new EventHandler(button1_MouseHover);
button1.MouseMove += new MouseEventHandler(button1_MouseMove);
void button1_MouseMove(object sender, MouseEventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
void button1_MouseHover(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
To add images to your resources: Projectproperties/resources/add/existing file
I think something like this:
btn.BackgroundImage = Properties.Resources.*Image_Identifier*;
Where *Image_Identifier* is an identifier of the image in your resources.
I made a quick project in visual studio 2008 for a .net 3.5 C# windows form application and was able to create the following code. I found events for both the enter and leave methods.
In the InitializeComponent() function. I added the event handler using the Visual Studio designer.
this.button1.MouseLeave += new System.EventHandler( this.button1_MouseLeave );
this.button1.MouseEnter += new System.EventHandler( this.button1_MouseEnter );
In the button event handler methods set the background images.
/// <summary>
/// Handles the MouseEnter event of the button1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void button1_MouseEnter( object sender, EventArgs e )
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}
/// <summary>
/// Handles the MouseLeave event of the button1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void button1_MouseLeave( object sender, EventArgs e )
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img1));
}
You can create a class based on a Button with specific images for MouseHover and MouseDown like this:
public class AdvancedImageButton : Button {
public Image HoverImage { get; set; }
public Image PlainImage { get; set; }
public Image PressedImage { get; set; }
protected override void OnMouseEnter(System.EventArgs e) {
base.OnMouseEnter(e);
if (HoverImage == null) return;
if (PlainImage == null) PlainImage = base.Image;
base.Image = HoverImage;
}
protected override void OnMouseLeave(System.EventArgs e) {
base.OnMouseLeave(e);
if (HoverImage == null) return;
base.Image = PlainImage;
}
protected override void OnMouseDown(MouseEventArgs e) {
base.OnMouseDown(e);
if (PressedImage == null) return;
if (PlainImage == null) PlainImage = base.Image;
base.Image = PressedImage;
}
}
This solution has a small drawback that I am sure can be fixed: when you need for some reason change the Image property, you will also have to change the PlainImage property also.