Visual Studio C #, Loop - c#

Visual Studio C #
I made a calculator, and now I have to make a calculator memory (event).
There are 4 components other than the calculator: one Textbox for the answer of the calculator, two Buttons for "M" and "M+", and one Lable to display the answer again.
When the user clicks the “M” button, the contents of the Answer TextBox should be copied to a memory variable. Also make it so that when the user moves the mouse over the label, the value in the memory variable will appear in this label, and then disappear, when the mouse moves away from the label. Also add one more button, an “M+” button. When the user clicks this button, the contents of the Results box will be added to Memory. You will need to use a Global Variable to store this data.
My problem is that the label doesn't appear when the mouse over the label, and also it doens't disappear when the mouse leave the label. How can I fix it?
And also, is this way the right way to use the Global variable?
Below is my code (I just put the code for "M" and "M+" buttons, not the code for the calculator).
private String ans;
private Double answer;
private Double answerPlus;
private void btnM_Click(object sender, EventArgs e)
{
ans = txtDisplay.Text;
answer = double.Parse(ans);
lblblank.Text = answer.ToString();
}
private void lblblank_MouseEnter(object sender, EventArgs e)
{
lblblank.Show();
lblblank.Text = answer.ToString();
}
private void lblblank_MouseLeave(object sender, EventArgs e)
{
lblblank.Hide();
}
private void btnMplus_Click(object sender, EventArgs e)
{
answerPlus = answer + double.Parse(ans);
lblblank.Text = answerPlus.ToString();
}

Storing variables
The way you store your values is fine.
Events
Once you call .Hide() the next MouseEnter/MouseLeave-event will not be triggered anymore. What you could do is to take a panel, or any layout element as a wrapper/parent-element for the label and then adjust your event-callbacks to something like that:
private void panel_MouseEnter(object sender, EventArgs e)
{
lblblank.Show();
lblblank.Text = answer.ToString();
}
private void panel_MouseLeave(object sender, EventArgs e)
{
lblblank.Hide();
}
Edit
~~~
What does it mean that any layout element as a parent-element for the
label? Could you explain more?
What I meant was to just create a new panel (or layout-element) and put the label into it as a child. See the picture below:
If you set that up correctly, the code snippet I posted above will work just fine. This solution does not prevent the MouseLeave event from triggering when your mouse enters the label. Therefore you could use an alternative solution using the MouseMove event.
Alternative
using System;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
this.InitializeComponent();
// Subscribe to the MouseMove event
this.panel.MouseMove += this.panel_MouseMove;
}
private void panel_MouseMove(object sender, MouseEventArgs e)
{
// Checks if current mouse position is within the panel
if (this.panel.Bounds.Contains(new Point(e.X, e.Y)))
{
// Current mouse position within the panel
this.label.Show();
return;
}
// Current mouse position outside the panel
this.label.Hide();
}
}
}

Related

Grabbing the textbox label

Hello im making my first project with about 10 different textboxes where the user puts data in. when he/she clicks the the textbox the textbox text clears and a virtual numpad form pops up and when he leaves the textbox the numpad "hides".
right now (or i would) i have 2 events for every textbox, a click event and a leave event,
private void sheetWidthBox_Enter(object sender, EventArgs e)
{
vnumPadForm.Location = PointToScreen(new Point(sheetWidthBox.Right, sheetWidthBox.Top));
vnumPadForm.Show();
}
Im sure there is a way of dynamically coding that in one event and just grabbing the label name. i have played around with it a bit on my numpad like this and it works good;
private void button_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
string num = b.Text;
SendKeys.SendWait(num);
}
Like that but instead i want to get the label name
right now (or i would) i have 2 events for every textbox, a click event and a leave event,
it works but very inefficient.
Change the name of the handler to something generic like "anyBox_Enter()", and update to the code below:
TextBox curTextBox = null;
private void anyBox_Enter(object sender, EventArgs e)
{
curTextBox = sender as TextBox;
vnumPadForm.Location = PointToScreen(new Point(curTextBox.Right, curTextBox.Top));
vnumPadForm.Show();
}
Note that I added a class level variable called "curTextBox" that gets set from the generic handler! This will track whatever TextBox was entered last.
Now, one by one, select each TextBox on your Form that you want to wire up to this common handler. After selecting each one, in the Properties Pane, click on the "Lightning Bolt" Icon to switch to the events for that control if they are not already showing. Find the "Enter" entry and change the dropdown to the right so that it says "anyBox_Enter".
Then in your button click handlers you can use the "curTextBox" variable to know where to send the key:
private void button_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
string num = b.Text;
if (curTextBox != null) {
curTextBox.Text = num; // or possibly APPEND this to the TB?
}
}

Winform copy button text to textbox using universal method

So this is a fairly straightforward thing, and I am just curious if there is a better way to do it to save lines of code. For class we are making a teletype machine. Basically there is a textbox, and a series of buttons A-Z and 0-9. When you click the button it adds the corresponding letter/number to the textbox. When you click send, it adds the contents of the textbox to a label and resets the textbox. Everything works and it only took a few minutes to build. However there is a mess of redundant lines and I was curious if there is a way to clean up the code with a method.
This is my current code.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + "A";
}
As you can see, it is very simplistic and straight forward. Click A, and "A" gets added to the textbox. However the Text property of the button is also just "A" and I want to know if there is a way to just copy the text property of that button and add it to the textbox string.
Something like this, except with a universal approach where instead of having to specify btn_A it just inherits which button to copy based on the button clicked. That way I can use the same line of code on every button.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + btn_A.Text;
}
You can use this which is more universal as the Control class contains the Text property. Also, using the best practice $"".
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
You can also assign the same event to each button. Create an event, say addControlTextOnClick and assign the same event to each button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void addControlTextOnClick(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
}
You can even shorten this more using this C# construct:
private void addControlTextOnClick(object sender, EventArgs e) =>
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";

C# Form - MouseClick will click the actual control after losing form focus

If you ever remove focus from any professional application like Chrome/FireFox/Visual Studio, and then reclick a button/menu item, it will actually click it as if you never lost focus.
How can I apply the same concept in C# WinForm? I tried many things like
private void form1_MouseClick(object sender, MouseEventArgs e)
{
BringToFront();
Activate();
}
Activate/focus/select/etc... nothing worked to react the same way, it always takes 3-4 clicks to actually click on a menu!
I thought about making a click event for every single control, but that seemed rather redundant.
Check this for example (Yellow Clicks)
You are right about Menues taking an extra click to get focus.
Which is extra annoying since the menue get highlighted anyway but doesn't react to the 1st click..
You can avoid that by coding the MouseEnter event:
private void menuStrip1_MouseEnter(object sender, EventArgs e)
{
// either
menuStrip1.Focus();
// or
this.Focus();
}
The downside of this is, that it is stealing focus from other applications, which is not something a well-behaved application should do..
So I think it is better to wait for a definitive user action; code the MouseDown event in a similar way..:
private void menuStrip1_MouseDown(object sender, MouseEventArgs e)
{
menuStrip1.Focus();
}
Or use the event that was made for the occasion:
private void menuStrip1_MenuActivate(object sender, EventArgs e)
{
menuStrip1.Focus();
}
I can't confirm a similar problem with Buttons or any other controls, though.
I have find trick to solve your problem. it work for me 100%
See this code:
dynamic elem1;
private void menuStrip1_MouseEnter(object sender, EventArgs e)
{
elem1 = sender;
}
private void menuStrip1_MouseLeave(object sender, EventArgs e)
{
elem1 = null;
}
private void Form1_Activated(object sender, EventArgs e)
{
if(elem1 != null){
elem1.PerformClick();
if (elem1.GetType().ToString() == "System.Windows.Forms.ToolStripMenuItem") elem1.ShowDropDown();
}
elem1 = null;
}
Here what happend.
When mouse enter button/menu item elem1 = this button/menu, and when mouse leave it set back to null.
so when form Activated we can call elem1.PerformClick() to click the button/menu item.

How can I count number of clicks anywhere on screen in C#?

I am trying to have a C# program running in the background on Windows that will print "Hello!" after seeing that the user has clicked his or her mouse 10 times. But not just in the console window, anywhere on the screen.
The following event handler for click-tracking is from msdn.microsoft.com:
private void OnMouseDownClickCount(object sender, MouseButtonEventArgs e) {
// Checks the number of clicks.
if (e.ClickCount == 1) {
// Single Click occurred.
lblClickCount.Content = "Single Click";
}
if (e.ClickCount == 2) {
// Double Click occurred.
lblClickCount.Content = "Double Click";
}
if (e.ClickCount >= 3) {
// Triple Click occurred.
lblClickCount.Content = "Triple Click";
}
}
But, I'm not sure how to actually use this. When I add this function anywhere, the MouseButtonEventArgs type is undefined.
What "using" statements do I need? How do I actually get this code to run properly -- do I call it once from main? What do I do to call it?
EDIT: Here is a picture showing Visual Studio not understanding MouseButtonEventArgs:
Initially You have to select the form and go to properties, Here you have to go events area and there is MouseClick event. Click that Mouse click. Go to Code behind window. there is the click event generated automatically. In that Form_MouseClick event you can count the number of clicks.
Initially declare a variable
int count = 0;
In method
Private void Form_MouseClick(object sender, MouseEventArgs e)
{
count++;
//add lable which will displays the count value
label.Text=count.ToString();
}
I think which will helps to count the clicks in the form.
I'm not entirely sure what you're trying to accomplish but..
To track user clicks I hooked up the "MouseDown" event on a form in a Windows Forms applications.
From there I check click counts in the event handler.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplicationTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent( );
this.MouseDown += Form1_MouseDown;
}
private void Form1_MouseDown( object sender, MouseEventArgs e )
{
// Count clicks
}
}
}

Toggle Group Box Visibility

I have two Group Boxes grpMeter and grpTag. I have to place grpMeter over grpTag.. both need same location and size..
On button click, I have to make them visible alternately. Is it possible? I tried many times but only 1 group box becomes visible. Maybe because of the overlapping problem. I tried with panel, but the same problem arises. Is there any solution?
public void ShowMeter()
{
grpMeter.Visible = true;
grpTags.Visible = false;
}
public void ShowTag()
{
grpTags.Visible = true;
grpMeter.Visible = false;
}
Place both group boxes next to each other so that they don't overlap and see if it works then. If you made it work, don't move the one group box with the mouse, but select it only and then set the coordinates manually in the Properties list.
That way you can prevent the one group box from accidentially becoming the child of the other group box.
Try this logic inside a button_click event:
private void btn_Click(object sender, EventArgs e)
{
if (grpTags.Visible)
ShowMeter();
else
ShowTag();
}
Try this:
private void button_Click(object sender, EventArgs e)
{
grpMeter.Visible = !grpMeter.Visible;
grpTags.Visible = !grpTags.Visible;
}
See the code below. The button Click will toggle visibilty. Also it's important that you set one of the groupboxes as visible and the other one as invisible in your constructor
using System;
using System.Windows.Forms;
namespace TestForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//This is important. Set one of them to be Visible and the other one to be invisible
grpMeter.Visible = false;
grpTags.Visible = true;
}
private void button1_Click(object sender, EventArgs e)
{
grpMeter.Visible = !grpMeter.Visible;
grpTags.Visible = !grpTags.Visible;
}
}
}
I am not sure but what you are looking for seems like FlowLayoutPanel. Then you can put group boxes next to each other and positioning will be handled automatically. This prevents accidentally putting one GroupBox into another or shifting locations. Also provides an easier working at design time.
One of the good way is to use RadioButton. Take two Radio buttons and place it inside a groupbox.
Something like this would work:
private void rdMeter_CheckedChanged(Object sender, EventArgs e)
{
grpMeter.Visible = rdMeter.Checked;
grpTag.Visible = !rdMeter.Checked;
}
private void rdTag_CheckedChanged(Object sender, EventArgs e)
{
grpTag.Visible = rdTag.Checked;
grpMeter.Visible = !rdTag.Checked;
}

Categories