How to change button background image on mouseOver? - c#

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.

Related

How can I show/hide form with checkbox?

Sorry, I am new to C# and am unsure what I am doing wrong.
Here is the code I am using:
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
frmSmallMenu sm = null;
if (chkSmallMenu.Checked)
{
if (sm is null || sm.IsDisposed)
{
sm = new frmSmallMenu();
}
sm.Show();
}
else
{
MessageBox.Show("close");
sm?.Close();
}
}
The window will open but when I uncheck the box nothing happens and I have no idea why.
I have tried looking for an answer but nothing has worked for me.
Try this:
frmSmallMenu sm = new frmSmallMenu();
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
if (chkSmallMenu.Checked == true)
{
sm.Show();
}
else
{
MessageBox.Show("close");
sm.Hide();
}
}
This modification of your code would probably do what you want by first looking whether the other Form is already running or not:
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// The following `uselessField ` is a `field`. See also https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property
/// `(Since it is `unused`, you would get a CS0169 Warning in the "Error List" window)
private int uselessField;
/// <summary>
/// **Event handler** of the "chkSmallMenu" `CheckBox` control on your `Form`.
/// (You would probably get an IDE1006 Info in your "Error List" window because
/// the control name and/or the event handler name respectively, starts with a lower case
/// https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/naming-rules)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
// the following `sm` is a `variable`. See also https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property
var sm = Application.OpenForms.OfType<frmSmallMenu>().FirstOrDefault();
// the following `Checked` **property** belongs to the WinForms Checkbox class and `IsDisposed` belongs to the other `Form`
if (chkSmallMenu.Checked)
{
if (sm?.IsDisposed != true)
{
sm = new frmSmallMenu();
}
sm.Show();
}
else
{
MessageBox.Show("close");
sm?.Close();
}
}
}
}
This fixed my issue:
frmSmallMenu sm = new frmSmallMenu();
private void chkSmallMenu_CheckedChanged(object sender, EventArgs e)
{
if (chkSmallMenu.Checked == true)
{
sm.Show();
}
else
{
MessageBox.Show("close");
sm.Hide();
}
}

I'm getting an exception of InvalidCastException

I want to get asp button ID from previous page and I'm getting an exception.
Here is my code for C#
public partial class ADD_MOBILE : System.Web.UI.Page
{
string BUTN_ID;
protected void Page_Load(object sender, EventArgs e)
{
Button button = (Button)sender;
string BUTTON_CLICKER_ID = button.ID;
BUTN_ID = BUTTON_CLICKER_ID;
}
protected void saveMOBILE_Click(object sender, EventArgs e)
{
if(BUTN_ID == "samsung"){ ... }
}
}
I'm getting exception at this point Button button = (Button)sender; why?
Okay, after going through your code it seems you want to get the button id so you can process some code based on that. Well, Let me make something clear, Page Load event will never give you the control that caused postback in sender object even if it gets triggered when you click a button and it posts back but it will NOT have the information in sender object for the control that posted it back.
For that you might want to use this approach from this James Johnson's answer to know which control caused postback:
/// <summary>
/// Retrieves the control that caused the postback.
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
private Control GetControlThatCausedPostBack(Page page)
{
//initialize a control and set it to null
Control ctrl = null;
//get the event target name and find the control
string ctrlName = page.Request.Params.Get("__EVENTTARGET");
if (!String.IsNullOrEmpty(ctrlName))
ctrl = page.FindControl(ctrlName);
//return the control to the calling method
return ctrl;
}
This will return the Control object that you can further dig more into.
Otherwise, the suitable and neat approach in your case would be to do it like this:
public partial class ADD_MOBILE : System.Web.UI.Page
{
string BUTN_ID; // I do not think it is necessary here.
protected void Page_Load(object sender, EventArgs e)
{
}
protected void saveMOBILE_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
if(button is null) return; // you can use == instead of keyword 'is'
if(button.ID.Equals("samsung"))
{
// DoStuff();
}
}
}
I hope you find it useful.

C# Perfom Image Search with WInodws.Forms GUI

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.

Moving Frameless Windows Form via Mouse Drag

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.

Rate limiting on the KeyUp event handler in C#

I'm wanting to validate the input on a text field as a user types. This functionality works fine, however I would like to rate limit the validation as it's hitting an external API. I'd like to only perform a validation after a user has not typed for 750ms.
ATM I'm simply using this:
private void Configure_Load(object sender, EventArgs e)
{
endpointBox.KeyUp += EndpointBox_KeyUp;
}
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
TestHTTP200(endpointBox.Text);
}
Use a Timer Control
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private void Configure_Load(object sender, EventArgs e)
{
endpointBox.KeyUp += EndpointBox_KeyUp;
myTimer.Tick +=new EventHandler(OnTimedEvent); //EDIT: should not be `ElapsedEventHandler`
myTimer.Interval=750;
}
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
myTimer.Stop();
myTimer.Start();
}
private void OnTimedEvent(Object myObject,EventArgs myEventArgs)
{
myTimer.Stop();
TestHTTP200(endpointBox.Text);
}
You would want a method equal to JavaScript's SetTimeout method. This can be cancelled when the user provides more input:
Code taken from here.
public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
{
System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) =>
{
method();
};
timer.AutoReset = false;
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
You can then use this in your key up handler:
void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
IDisposable timeout = SetTimeout(() => TestHTTP200(endpointBox.Text), 750);
if (this.currentTimeout != null) {
this.currentTimeout.Dispose();
this.currentTimeout = timeout;
}
}
This is the basic principle at least, every time the user types you reinitiate a 750ms timeout to do your thing, and cancel any pending timers.
Update: complete code sample:
public partial class Form1 : Form
{
private IDisposable currentTimeout;
public Form1()
{
InitializeComponent();
}
private void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
IDisposable timeout = TimerHelper.SetTimeout(() => TestHTTP200(EndpointBox.Text), 750);
if (this.currentTimeout != null)
{
this.currentTimeout.Dispose();
this.currentTimeout = timeout;
}
}
private void TestHTTP200(string text)
{
//...
}
}
public class TimerHelper
{
public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
{
System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) =>
{
method();
};
timer.AutoReset = false;
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
}
using System;
namespace Azine_Library.Misc
{
/// <summary>
/// Represents a way to delay something, eg. something an event handler does, update-ion of a control, object or to run a method, This class '<see cref="DelayUpdate"/>'
/// is intended to be used as a delayer of some sort and contains an event, '<see cref="PushUpdate"/>' that would be subcribed to an event handler where then the code
/// intended to be delayed would go. This object also contains a method, '<see cref="delay"/>' that when called delays the code written/located within the event handler
/// that is handling the '<see cref="PushUpdate"/>' event. The method, <see cref="delay"/> should be called from an event handler or a method of some sort that would orginally
/// execute the code written/located within the event handler described above also. An example of how this object can interact with another object is described and documented in great detail
/// within the documentation for "Azine_Library", also an example program is available with the documentation.
/// </summary>
public class DelayUpdate
{
// Written, 17.06.2017
#region Fields / Properties
/// <summary>
/// Occurs when the provided time (interval:) has elapsed
/// </summary>
public event EventHandler PushUpdate;
/// <summary>
/// READONLY. the amount of times the timer has ticked since the last call to delay, (DelayUpdate.delay).
/// </summary>
public int updateCounter
{
get;
private set;
}
/// <summary>
/// The amount of time [this] waits for until it pushes the update. (Milliseconds). default value: '500'.
/// </summary>
public int interval
{
get;
set;
}
/// <summary>
/// Holds the amount of times [this] raises the "DelayUpate.PushUpdate" event every call to DelayUpdate.delay() method. default value: '1'.
/// </summary>
public int updatesPerPush
{
get;
set;
}
private System.Diagnostics.Stopwatch stopWatch;
private System.Windows.Forms.Timer timer;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of type, 'DelayUpdate'; sets the classes' properties to the defaults.
/// </summary>
public DelayUpdate()
{
//Initializing Variables
this.updateCounter = 0;
this.interval = 500;
this.updatesPerPush = 1;
this.stopWatch = new System.Diagnostics.Stopwatch();
this.timer = new System.Windows.Forms.Timer();
//Sub-ing Events
this.timer.Tick += this.Timer_Tick;
}
#endregion
#region Methods
/// <summary>
/// Delays the raising of the event, PushUpdate; call this method when a property of an object has changed. eg, TextBox.TextChanged => DelayUpdate.delay();
/// </summary>
public void delay()
{
// Written, 13.06.2017
this.timer.Start();
this.stopWatch.Restart();
this.updateCounter = 0;
}
#endregion
#region Events
/// <summary>
/// Raises the 'DelayUpdate.PushUpdate' event.
/// </summary>
private void onPushUpdate()
{
//Written, 26.05.2017 : 5:22pm
if (PushUpdate != null)
PushUpdate.Invoke(this, new EventArgs());
}
#endregion
#region Event Handlers
private void Timer_Tick(object sender, EventArgs e)
{
// Written, 13.06.2017
if (this.stopWatch.ElapsedMilliseconds > this.interval)
{
if (this.updateCounter < this.updatesPerPush)
{
this.timer.Stop();
this.onPushUpdate();
}
this.updateCounter++;
}
}
#endregion
}
}
And this is how you would use this class, DelayUpdate.cs:
Say you have a WinForm that searches a directory for files which has a textbox called, "search_textBox" and has a textChanged event handler attached, :
namespace DelayUpdateExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
}
private void Search_textBox_TextChanged(object sender, EventArgs e)
{
}
}
}
You would make a reference to the class, DelayUpdate.cs and initialize it. Subscribe to the DelayUpdate.PushUpdate event like so:
private DelayUpdate delayUpdate;
public Form1()
{
InitializeComponent();
this.delayUpdate = new DelayUpdate()
{
interval = 500,
updatesPerPush = 1,
};
this.delayUpdate.PushUpdate += this.DelayUpdate_PushUpdate;
this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
}
private void DelayUpdate_PushUpdate(object sender, EventArgs e)
{
throw new NotImplementedException();
}
Within the textChanged event handler you would make a call to DelayUpdate.delay() like so..
private void Search_textBox_TextChanged(object sender, EventArgs e)
{
this.delayUpdate.delay();
}
And the code that you would want to delay would then go in the DelayUpdate_PushUpdate(object, EventArgs) that you subscribed to. like so:
private void DelayUpdate_PushUpdate(object sender, EventArgs e)
{
// You would search the directory here..
// Code that you want to delay would go here.
}

Categories

Resources