Regroup button events in one event - c#

I use 6 different buttons doing practically the same thing.
private void VisaCreaDoc_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.CREADOC);
}
private void VisaTravaux_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.TRAVAUX);
}
private void VisaRemiseOuvrageIR_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.REMISEOUVRIR);
}
private void VisaRemiseOuvrageExpl_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.REMISEOUVREXPL);
}
private void VisaMES_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.MISEENSERVICE);
}
private void VisaEncodageArchivage_Click(object sender, RoutedEventArgs e)
{
ViewModel.ValidateItem(InfosPosteViewModel.ENCODAGEARCHIVAGE);
As you can see, they're using a function from the ViewModel with a different parameter.
Is there any way to regroup the 6 button events to have only one and kind of pass the parameter directly in the XAML call or something similar to avoid having the "code duplication" ?

Not sure if you like it "better" but you can check which button was clicked inside the handler:
void HandleButton_Click(object sender, RoutetEventArgs e)
{
if (sender is Button b)
{
if (b == VisaCreaDoc) # VisaCreaDoc is the given name of your button instace in xaml
ViewModel.ValidateItem(InfosPosteViewModel.CREADOC);
else if (b == VisaTravaux)
ViewModel.ValidateItem(InfosPosteViewModel.TRAVAUX);
else if (...) // etc.
}
}
You can spice it up with a switch pattern matching to get rid of the if / else if / else if / ... chains.

Maybe you can avoid some duplicate code by creating a command for the ViewModel function (see Introduction to WPF Commands). As far as I know you can also define a CommandParameter in XAML.

Related

Raise an Event Except when something happpen

Scenario: Only If the user follow the path Click on ListView > Click on Button the Button1 do something.
In other word I want to check in Button1_Click(object sender, EventArgs e) if the previous focus was on ListView.
So I tried this:
private void ListView_Test_Leave(object sender, EventArgs e)
{
_focusedControl = null;
}
I want raise previous event except when this event is raised:
private void Button1_Click(object sender, EventArgs e)
{
if(_focusedControl == listView_Test)
{
// ...
}
}
Edit: I have a variable that holds a reference to the currently focused control:
private Control _focusedControl;
and I update it in this way:
private void ListView_Test_GotFocus(object sender, EventArgs e)
{
_focusedControl = (Control)sender;
}
If the user follow the path Click on ListView > Click on Button I want raise only the Button1_Click event, in all other case I want normal raise.
You could use a helper variable.
bool wasRaised=false;
private void Button1_Click(object sender, EventArgs e) { wasRaised=true;}
Then you can check that variable in your event, and only run if it is false.

Get the text value of the button that was clicked

I am trying to get the text value from a button that was clicked. In my head, it looks something like this:
private void button2_Click(object sender, EventArgs e)
{
string s = thisbutton.text
}
The object which fired the event is sender, so:
private void button2_Click(object sender, EventArgs e)
{
string s = (sender as Button).Text;
}
Just cast the sender Object to a Button Object and access the text attribute :
protected void btn_Click (object sender, EventArgs e){
Button btn = sender as Button;
string s= btn.Text
}
Should be like this:
private void button2_Click(object sender, EventArgs e)
{
string s = this.button2.Text;
}
In every build in event handler there are 2 parameters sender and e.Sender takes reference to that object which fires the event.The second parameter e holds some information about the event(such as the location of pointer and other of this kind)
You need only bring it to Button type and get what information you want
try and apply this example in your button event
private void button_click(object sender, EventArgs e)
{
var getValue = ((Button)sender).Text; //this will get the value of the text using sender
}
This was asked some time ago and the platform in my case may be a little different to what the OP used but I arrived at the same question for GTK.
I am developing in Xaramin / Visual Studio in OSX using GTK2+, and for me the original accepted answer is close, but yields an error that .Text doesn't exist. In my case, it needs to be Label. This works for me:
protected void Button_Clicked(object sender, EventArgs e)
{
Button btn = sender as Button;
lblWhichButton.Text = btn.Label;
if (btn.Label == "<<<" )
i--;
else
i++;
lblCounter.Text = "" + i;
}

add click event to many control

I have many controls in my form. for example 120 labels in one panel. and i want when user clicked on each label just call same function with same parameter.
Now i used like this :
private void label67_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
private void label66_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
private void label65_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
private void label64_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
now can i make easy way to call ChangeToTextbox function when user clicked in any label?
Add the same OnClick handler for all labels on the panel:
private void Form1_Load(object sender, EventArgs e)
{
panel1.Controls.OfType<Label>().ToList().ForEach(l => l.Click += label_Click);
}
private void label_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
Find all your controls then just add the handler via code;
List<Control> controls = GetAllMyControls();
foreach(Control control in controls)
{
control.OnClick += (o, e) => { ChangeToTextBox(o); }
}
The syntax should be very similar for both web and winform solutions.
It can be easily achieved by using following approach: Pls give a try,
1) Go to Windows Forms Designer and click the first Label control to select it. Then hold down the CTRL key while you click each of the other labels to select them. Be sure that every label is selected.
2) Then go to the Events page in the Properties window. Scroll down to the Click event, and type label_Click in the box
3) Press ENTER. The IDE adds a Click event handler called label_Click() to the code, and hooks it to each of the labels.
private void label_Click(object sender, EventArgs e)
{
ChangeToTextbox(sender);
}
Reference: http://msdn.microsoft.com/en-us/library/dd553231.aspx

call a method from another method in Code behind C#

I need to call btn_submit_Click(object sender, EventArgs e) from another method protected void Timer1_Tick(object sender, EventArgs e) which normally calls by a button click.
Now here in Timer1_Tick compares a time and if current time exceeds, i need to call btn_submit_Click(object sender, EventArgs e) automatically.
protected void Timer1_Tick(object sender, EventArgs e)
{
DateTime et = DateTime.Parse(Session["endtime"].ToString());
if (DateTime.Now.TimeOfDay >= et.TimeOfDay)
{
// btn_submit_Click();
Response.Redirect("Welcome.aspx");
}
else
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
}
Please suggest me a way to do this.
Personally I would take a slightly different approach. You're not actually trying to say that a button was clicked - you're just interested in the same side effects as a button click. So extract a third method which only has the relevant parameters (there may not be any) and call that method from both btn_submit_Click and Timer1_Tick. That way you don't have to come up with a sender and EventArgs for a button click which didn't happen. So for example:
protected void btn_submit_Click(object sender, EventArgs e)
{
// Maybe validation?
Submit();
}
protected void Timer1_Tick(object sender, EventArgs e)
{
DateTime et = DateTime.Parse(Session["endtime"].ToString());
if (DateTime.Now.TimeOfDay >= et.TimeOfDay)
{
Submit();
Response.Redirect("Welcome.aspx");
}
else
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
}
private void Submit()
{
// Common code to execute on either the timer tick or button click
}
Jon Skeet mentioned the right approach. Refactor the code in your btn_submit_click into a central method that can be called by both Button and Timer. But you can still do submit_click(sender, e)
protected void Timer1_Tick(object sender, EventArgs e)
{
....
btn_submit_Click(sender, e);
...
}

Update form from shared event

I've got a form I've created with 4 buttons that will modify a listView, each with their own click event. I'm wondering as a way to avoid adding a method call in each of these buttons if it their is an event available for after a button has finished executing its click event?
The reason for this is so I can update the listView which will in turn update a webBrowser
Here's an example which results in "1" and then "all" being displayed to the user when button 1 is clicked, "2" and then "all" when button 2 is clicked etc etc.
Note: you don't want to do it like this - see comments
public Form1()
{
InitializeComponent();
foreach(var b in Controls.OfType<Button>())
b.Click += new EventHandler(AnyButton_Click);
}
void AnyButton_Click(object sender, EventArgs e)
{
MessageBox.Show("all");
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("1");
}
private void button3_Click(object sender, EventArgs e)
{
MessageBox.Show("3");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("2");
}

Categories