C# Perfom Image Search with WInodws.Forms GUI - c#

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.

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.

Progress bar does not update on separate form from VSTO addin

On button click in Word VSTO addin, I want to show the form with progress bar and update its value.
Even though I used BackgroundWorker and its events (DoWork, ProgressChanged), progress of the progress bar does not update accordingly
private void extractDataButton_Click(object sender, RibbonControlEventArgs e)
{
//On button click of addin
ProgressNotifier progressNotifier = new ProgressNotifier();
progressNotifier.Show();
progressNotifier.UpdateProgressBar(10);
// Does the work which lasts few seconds
HandleRetrievedData(data);
progressNotifier.UpdateProgressBar(100);
progressNotifier.Close();
}
// Progress bar form
public partial class ProgressNotifier : Form
{
public ProgressNotifier()
{
InitializeComponent();
}
public void UpdateProgressBar(int progress)
{
backgroundWorker1.ReportProgress(progress);
progressBar_extractionProgress.Update();
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.progressBar_extractionProgress.Value = e.ProgressPercentage;
}
}
Although this is an older style using delegates, you might need a check that the form is available for updating. Below is older code - there are examples using newer syntax not requiring delegates - but generally illustrates a resolve.
private delegate void StatusMessage();
/// <summary>
/// Simple methods for setting active cube list before connecting
/// </summary>
private void SetDefaultNode()
{
if (this.ActiveCubeStatus.InvokeRequired)
{
StatusMessage d = new StatusMessage(SetDefaultNodeDirect);
this.Invoke(d);
}
else
{
SetDefaultNodeDirect();
}
}
/// <summary>
/// Simple methods for setting active cube list before connecting
/// </summary>
private void SetDefaultNodeDirect()
{
//clears treeveiw
ClearActiveCubes();
//create default inactive node
TreeNode nodeDefault = new TreeNode();
nodeDefault.Name = "Waiting";
nodeDefault.Text = "Waiting on connection...";
this.ActiveCubeStatus.Nodes.Add(nodeDefault);
nodeDefault = null;
}

How to create animated glow effect on Button Hover with C#?

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
}
}

How to change button background image on mouseOver?

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.

Categories

Resources