It goes like this, I have a numericUpDown which has a max value of 4. I want to make it so if the value is 1 only one button appears, if value is 2, two buttons appears, etc. How can I manage to do this in code ? I am using a timer and on every tick it checks if the value of the numericUpDown changes and if its changed it adds buttons, but how can I do the opposite thing, if value decreases, remove buttons? For example if I have the value of 4 and I already have 4 buttons appeared if I decrease with ONE, only one button should go away. How can I do this ?
private void timer1_Tick(object sender, EventArgs e)
{
if (numericUpDown1.Value == 1)
{
metroComboBox3.Show();
}
else if (numericUpDown1.Value == 2)
{
metroComboBox4.Show();
}
}
Simply do a double click on you numericUpDown in design, you dont need a timer.
You will get private void numericUpDown1_ValueChanged
Afther that your code should look like this:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if (numericUpDown1.Value == 1)
{
metroComboBox3.Show();
}
else if (numericUpDown1.Value == 2)
{
metroComboBox4.Show();
}
}
If you have to do it with a timer then this is the way to go:
private void timer1_Tick(object sender, EventArgs e)
{
var buttons = new [] { button1, button2, button3, button4, };
for (var i = 0; i < buttons.Length; i++)
{
buttons[i].Visible = numericUpDown1.Value - 1 >= i
}
}
But I would use the numericUpDown1.ValueChanged event and do this:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
var buttons = new [] { button1, button2, button3, button4, };
for (var i = 0; i < buttons.Length; i++)
{
buttons[i].Visible = numericUpDown1.Value - 1 >= i
}
}
Related
This is my code
int Moneycount;
private void mButton_Click(object sender, EventArgs e)
{
Moneycount++;
MoneyCount.Text = Moneycount.ToString();
}
private void level1_Click(object sender, EventArgs e)
{
}
"mButton" is incremented by 1 every time I press it,
so I want it to be incremented by 2 instead of 1 after I press "level1"
So if I understand you correctly, you want mButton to increment MoneyCount by one every time you press it. But after pressing level1, mButton should increment by 2 instead.
Try this:
int Moneycount;
int amountToIncrement = 1;
private void mButton_Click(object sender, EventArgs e)
{
Moneycount += amountToIncrement;
MoneyCount.Text = Moneycount.ToString();
}
private void level1_Click(object sender, EventArgs e)
{
amountToIncrement = 2;
}
Instead of level1 being an actual Button, it might be useful to make it a Checkbox instead, and then make it look like a button by setting the Appearance property to Button in the designer. Here is a simple example where clicking on mButton looks at the Checked state of level1 to determine the correct increment value. At the same time, toggling the checked state of level1 sets the Increment value of the NumericUpDown control so that the Up/Down arrows also use the correct value of 1 or 2.
Example of coding the MainForm that has the behavior you describe:
public partial class MainForm : Form , INotifyPropertyChanged
{
public MainForm()
{
InitializeComponent();
level1.Appearance = Appearance.Button;
numericUpDown.DataBindings.Add(
nameof(NumericUpDown.Value),
this,
nameof(Moneycount),
false,
DataSourceUpdateMode.OnPropertyChanged);
}
private void mButton_Click(object sender, EventArgs e)
{
Moneycount += level1.Checked ? 2 : 1;
}
private void level1_CheckedChanged(object sender, EventArgs e)
{
// Clicking up/down arrows increments 1 or 2
numericUpDown.Increment = level1.Checked ? 2 : 1;
}
public int Moneycount
{
get => _moneyCount;
set
{
if(!Equals(_moneyCount, value))
{
_moneyCount = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Moneycount)));
}
}
}
int _moneyCount = 0;
public event PropertyChangedEventHandler PropertyChanged;
}
Try
Moneycount += 2;
this increments by two
Relatively new to C#. I have to make a Tic Tac Toe. I am thinking of using only one method to change my button properties.
This is what I imagine.
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
ChangeButton(count);
}
public int ChangeButton(int i)
{
if(count % 2 == 0)
{
// button.text = x
// i want to be able to change the text of whichever button is clicked
}
else
{
// button.text = o
}
// button.enable = false
// I want to disable whichever button is clicked
i++;
return i;
}
I don't know should I do the // parts. Hope you can help me. Thanks!
If you have several buttons all calling the same click event, you can identify the button from the sender parameter:
Button btn = sender as Button;
Then you can change the text for that button:
btn.Text = count++ % 2 == 0 ? "x" : "o";
All in your click event:
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
btn.Text = count++ % 2 == 0 ? "x" : "o";
btn.Enabled = false;
}
Please, I want to know how to make two events on one button like: when I first click on the button display an image and while still in debugging mode the second time I click
display another image. What are some ways to do this?
You can make something like:
protected void Button1Click(object sender, EventArgs e)
{
if (Img1.Visible == false)
{
Img1.Visible = true;
}
else
{
Img2.Visible = true;
}
}
I don't think you need two (or more) events to do what you want, you only need to trace how many times you clicked the button, for example using an instance variable.
private int clicks = 0;
protected void myButton_Click(object sender, EventArgs e)
{
if(clicks == 1)
{
// do something
}
if(clicks == 2)
{
// do other things
}
if(clicks > 2)
{
// something else
}
clicks++;
}
What about something like this: just make sure to declare the counter outside the button
int clickedCount = 0;
private void button1_Click(object sender, EventArgs e)
{
clickedCount++;
if (clickedCount % 2 == 0) { pictureBox1.ImageLocation = #"path"; } else { pictureBox1.ImageLocation = #"path"; }
}
When I run my program with a listbox everything works after selecting the items and pressing enter, but when I press the clear button and I select the items again and press enter nothing happens. I've tried the following for the clear button and they clear my label text and the selected listbox but I can no longer produce another output when I try pressing enter button again after selecting the items.
public partial class frmLabSix : Form
{
public string strCakes;
public int cakeCost;
public frmLabSix()
{
InitializeComponent();
}
private void lstCakes_SelectedIndexChanged(object sender, EventArgs e)
{
for (int index = 0; index < lstCakes.SelectedItems.Count; index++)
{
strCakes += Environment.NewLine + lstCakes.SelectedItems[index].ToString();
if (lstCakes.SelectedIndices[index] == 0) cakeCost += 18;
if (lstCakes.SelectedIndices[index] == 1) cakeCost += 25;
if (lstCakes.SelectedIndices[index] == 2) cakeCost += 40;
if (lstCakes.SelectedIndices[index] == 3) cakeCost += 30;
}
}
private void lblOrdered_Click(object sender, EventArgs e)
{
}
private void btnEnter_Click(object sender, EventArgs e)
{
double tax = 1.13;
lblOrdered.Text = "You have ordered: " + strCakes + '\n' + "Total Cost: " + (tax * cakeCost).ToString("C");
lblOrdered.Visible = true;
}
private void btnClear_Click(object sender, EventArgs e)
{
lstCakes.SelectedItems.Clear();
lblOrdered.Visible = false;
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
}
Can someone tell me why this is?
This line of code hides your label.
lblOrdered.Visible = false;
You make your label invisible on clear button click. Do you reset its visibility after?
I don't know, what happens in other part of your code, but it should probably be like this:
// if the label is not visible, the next line won't make it visible implicitly
lblOrdered.Text = ...
//you should set label's visibility explicitly
if (!lblOrdered.Visible)
lblOrdered.Visible = true;
Setting label's text doesn't make it visible. If you hide it with your own code, you should make label visible explicitly as well.
I can catch a single-click on a TextBlock like this:
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("you single-clicked");
}
I can catch a double-click on a TextBlock like this:
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (e.ClickCount == 2)
{
MessageBox.Show("you double-clicked");
}
}
}
But how do I catch them both on a single TextBlock and differentiate between the two?
You need to fire the event after the click sequence is over... when is that? I suggest using a timer. The MouseDown event would reset it and increase the click count. When timer interval elapses it makes the call to evaluate the click count.
private System.Timers.Timer ClickTimer;
private int ClickCounter;
public MyView()
{
ClickTimer = new Timer(300);
ClickTimer.Elapsed += new ElapsedEventHandler(EvaluateClicks);
InitializeComponent();
}
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
ClickTimer.Stop();
ClickCounter++;
ClickTimer.Start();
}
private void EvaluateClicks(object source, ElapsedEventArgs e)
{
ClickTimer.Stop();
// Evaluate ClickCounter here
ClickCounter = 0;
}
Cheers!
If you need to detect the difference, I suggest you use a control such as Label that does the work for you:
label.MouseDown += delegate(object sender, MouseEventArgs e)
{
if (e.ClickCount == 1)
{
// single click
}
};
label.MouseDoubleClick += delegate
{
// double click
};
EDIT: My advice was following from documentation on MSDN:
The Control class defines the
PreviewMouseDoubleClick and
MouseDoubleClick events, but not
corresponding single-click events. To
see if the user has clicked the
control once, handle the MouseDown
event (or one of its counterparts) and
check whether the ClickCount property
value is 1.
However, doing so will give you a single click notification even if the user single clicks.
You must use a timer to differentiate between the two. Add a timer to your form in the GUI (easiest that way - it will automatically handle disposing etc...). In my example, the timer is called clickTimer.
private bool mSingleClick;
private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (e.ClickCount < 2)
{
mSingleClick = true;
clickTimer.Interval = System.Windows.Forms.SystemInformation.DoubleClickTime;
clickTimer.Start();
}
else if (e.ClickCount == 2)
{
clickTimer.Stop();
mSingleClick = false;
MessageBox.Show("you double-clicked");
}
}
}
private void clickTimer_Tick(object sender, EventArgs e)
{
if (mSingleClick)
{
clickTimer.Stop();
mSingleClick = false;
MessageBox.Show("you single-clicked");
}
}
I did it this Way and it works perfectly
If e.Clicks = 2 Then
doubleClickTimer.Stop()
ElseIf e.Clicks = 1 Then
doubleClickTimer.Enabled = True
doubleClickTimer.Interval = 1000
doubleClickTimer.Start()
End If
Private Sub doubleClickTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles doubleClickTimer.Tick
OpenWebPage("abc")
doubleClickTimer.Stop()
End Sub
You are simply can use MouseDown event and count click number, like this:
if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
{
// your code here
}
My suggestion, implemented in a UserControl by simply using a Task:
private int _clickCount = 0;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
_clickCount = e.ClickCount;
}
protected override async void OnPreviewMouseUp(MouseButtonEventArgs e)
{
if (_clickCount > 1)
{
//apparently a second mouse down event has fired => this must be the second mouse up event
//no need to start another task
//the first mouse up event will be handled after the task below
return;
}
await Task.Delay(500);
if (_clickCount == 1)
{
//single click
}
else
{
//double (or more) click
}
}
The drawback of all these solutions is, of course, that there will be a delay before actually responding to the user's action.
You could do it on MouseUp instead of MouseDown. That way you can ask the ClickCount property for the total number of clicks, and decide what to do from that point.
It's my working solution :)
#region message label click --------------------------------------------------------------------------
private Timer messageLabelClickTimer = null;
private void messageLabel_MouseUp(object sender, MouseButtonEventArgs e)
{
Debug.Print(e.ChangedButton.ToString() + " / Left:" + e.LeftButton.ToString() + " Right:" + e.RightButton.ToString() + " click: " + e.ClickCount.ToString());
// in MouseUp (e.ClickCount == 2) don't work!! Always 1 comes.
// in MouseDown is set e.ClickCount succesfully (but I don't know should I fire one clicked event or wait second click)
if (e.ChangedButton == MouseButton.Left)
{
if (messageLabelClickTimer == null)
{
messageLabelClickTimer = new Timer();
messageLabelClickTimer.Interval = 300;
messageLabelClickTimer.Elapsed += new ElapsedEventHandler(messageLabelClickTimer_Tick);
}
if (! messageLabelClickTimer.Enabled)
{ // Equal: (e.ClickCount == 1)
messageLabelClickTimer.Start();
}
else
{ // Equal: (e.ClickCount == 2)
messageLabelClickTimer.Stop();
var player = new SoundPlayer(ExtraResource.bip_3short); // Double clicked signal
player.Play();
}
}
}
private void messageLabelClickTimer_Tick(object sender, EventArgs e)
{ // single-clicked
messageLabelClickTimer.Stop();
var player = new SoundPlayer(ExtraResource.bip_1short); // Single clicked signal
player.Play();
}
#endregion
My issue was with single/double-clicking rows in a DataGrid in WPF. For some reason the ButtonDown events weren't firing, only the OnMouseLeftButtonUp event was. Anyway, I wanted to handle the single-click differently from the double-click. It looks me a little time (I'm sure the solution isn't perfect, but it appears to work) to distill the problem down until I got it down to the below. I created a Task which calls an Action and that Action's target can be updated by a second click. Hope this helps someone!
private Action _clickAction;
private int _clickCount;
private void Grid_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("Button Click Occurred");
_clickCount++;
if (_clickCount == 1)
{
_clickAction = SingleClick;
}
if (_clickCount > 1)
{
_clickAction = DoubleClick;
}
if (_clickCount == 1)
{
Task.Delay(200)
.ContinueWith(t => _clickAction(), TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(t => { _clickCount = 0; });
}
}
private void DoubleGridClick()
{
Debug.WriteLine("Double Click");
}
private void SingleGridClick()
{
Debug.WriteLine("Single Click");
}