Adding delegate functions first single use - c#

I have a button which slides out a menu using a storyboard by calling begin() on it like so
private void ShareBtn_Click(object sender, RoutedEventArgs e)
{
SlideIn.Begin();
}
On the grid which then slides out there are buttons.
Each button then slides the grid back and when that storyboard completes the action for the button then runs so like so,
private void PictureBtn_Click(object sender, RoutedEventArgs e)
{
CertificateDisplay.SaveAsPicture();
}
private void FacebookBtn_Click(object sender, RoutedEventArgs e)
{
App.facebookSuccess = false;
NavigationService.Navigate(new Uri("/FBLogin.xaml", UriKind.Relative));
}
private void SMSBtn_Click(object sender, RoutedEventArgs e)
{
SlideOut.Begin();
SlideOut.Completed += delegate(object s, EventArgs se) { SlideOut_Completed(s, se, "Email"); };
}
private void EmailBtn_Click(object sender, RoutedEventArgs e)
{
SlideOut.Begin();
SlideOut.Completed += delegate(object s, EventArgs se) { SlideOut_Completed(s, se, "Email"); };
}
void SlideOut_Completed(object sender, EventArgs e, String shareType)
{
switch (shareType)
{
case "Email":
...
default:
break;
}
}
The flaw I encountered if that I cannot remove the anonymous functions from the event stack.
I've managed to solve it by making shareType a common variable for all of the above functions and not using a anonymous delegate and then removing the "named" functions from the event stack when OnNavigatedFrom is called.
Is there a way to do this by still using those delegates because it looks neater?

One option is to remove it within the handler itself:
EventHandler handler = null;
handler = delegate(object s, EventArgs se) {
SlideOut_Completed(s, se, "Email");
SlideOut.Completed -= handler;
};
SlideOut.Completed += handler;
SlideOut.Begin();

Why assign the Completed event handler EmailBtn_Click at each click? Do it in the form constructor or in the form load event.

Related

DevExpress: raising GridView events

Tell me a method by which in C # it would be possible to generate a GridView Event, for example, FocusedRowChanged, like the on ..... methods for WinForms?
If you want to create an Event like FocusedRowChanged
You can use this codes
//using DevExpress.XtraGrid.Views.Base;
//the All is ok
public event FocusedRowChangedEventHandler MyFocusedRowChanged;
//Or
public event EventHandler<FocusedRowChangedEventArgs> MyFocusedRowChanged2;
If you want to handle the FocusedRowChanged event,
You can use this codes
private void YourForm_Load(object sender, EventArgs e)
{
gridView.FocusedRowChanged += GridView_FocusedRowChanged;
this.MyFocusedRowChanged += GridView_FocusedRowChanged;
this.MyFocusedRowChanged2 += GridView_FocusedRowChanged;
}
private void GridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
//your code
throw new NotImplementedException();
}
If you want to raise FocusedRowChanged,
You can use this codes
private void YourForm_Load(object sender, EventArgs e)
{
//gridView.FocusedRowChanged += GridView_FocusedRowChanged;
//this.MyFocusedRowChanged += GridView_FocusedRowChanged;
//this.MyFocusedRowChanged2 += GridView_FocusedRowChanged;
//invoke the handle method
GridView_FocusedRowChanged(gridView, new FocusedRowChangedEventArgs(-1, gridView.FocusedRowHandle));
//or change focused row to fire event
gridView.FocusedRowHandle++;
}
Which one do you mean?

C# WinForm: contextMenuStrip throws InvalidOperationException after .Show() method when called from BackgroundWorker_ProgressChanged event [duplicate]

This question already has answers here:
How do I update the GUI from another thread?
(47 answers)
Closed 3 years ago.
I have a WindowsForm in C# with a TrayIcon including a contextMenuStrip with a ToolStripTextBox, a FileSystemWatcher and a BackgroundWorker.
The FileSystemWatcher throws an event when a new file is created which then starts the BackgroundWorker. The BackgroundWorker reports progress which updates a ToolStripTextBox on the TrayIcon in the ProgressChanged event handler.
Curiously this works fine as long as the ToolStripMenu has not been visible since the start of the program. As soon as I right-click on the TrayIcon to show the ToolStripMenu (regardless of the BackgroundWorker being idle or not), the ToolStripTextBox starts to throw an InvalidOperationException (invalid cross-thread operation) every time I try to update its .Text property.
When I start the BackgroundWorker from a button click event it all works fine, too. I can see the ToolStripTextBox updating.
What is different when I start the BackgroundWorker from the FileSystemWatcher event? Or rather what is different after showing the contextMenuStrip? Does the contextMenuStrip belong to another thread after showing?
I might find another way to show the progress instead of the ToolStripTextBox but I am curious to know what causes this. I'd be very glad if you could help.
Minimal code example below.
public partial class Form1 : Form
{
FileSystemWatcher watcher = new FileSystemWatcher();
string watcherpath = #"C:\Temp\files";
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
watcher.Path = watcherpath;
watcher.Created += Watcher_Created;
watcher.EnableRaisingEvents = true;
bgw = new BackgroundWorker();
bgw.DoWork += Bgw_DoWork;
bgw.RunWorkerCompleted += Bgw_RunWorkerCompleted;
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.ProgressChanged += Bgw_ProgressChanged;
}
private void Bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
toolStripTextBox1.Text = $"Progress: {e.ProgressPercentage}%";
}
private void Bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done!");
}
private void Bgw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(1000);
(sender as BackgroundWorker).ReportProgress(i * 10);
}
}
private void Watcher_Created(object sender, FileSystemEventArgs e)
{
File.Delete(e.FullPath);
bgw.RunWorkerAsync();
}
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Close();
}
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
contextMenuStrip1.Show(Cursor.Position);
}
private void button1_Click(object sender, EventArgs e)
{
bgw.RunWorkerAsync();
}
}***
Please try below code
private void Bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
SetToolStripText(e.ProgressPercentage)
}
private void SetToolStripText(object ProgressPercentage)
{
this.BeginInvoke((MethodInvoker)delegate { this.toolStripTextBox1.Text = $"Progress: {e.ProgressPercentage}%";
}

how to fix this EventArgs c#

I'm trying to build my own Simple Calculator.
I have this method with 10 references (from 0-10)
private void button_Click_1(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.ToString();
}`
Everything is working but the text sent to the TextBox come with extra things that I don't need.
I just want to show the number that I clicked on the calculator. I want to hide the "System.windows.forms.button, Text:" and show only the 7(in this case)
Use the Button.Text property of Button instead of ToString()
tb.Text += b.Text;
As Adil points out just use the Text property.
A further improvement can be made to your code base by instead of using the generated Event handler, create a single reusable event handler
instead of
private void button_Click_1(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}
private void button_Click_2(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}
private void button_Click_3(object sender, EventArgs e)
{
...
You could instead just have the single event handler. Remember to update your pointers on your buttons to point to this event handler.
private void numericButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}`

C# WinForm multiple click event handlers for similar function

I have a few toolStripMenuItems that act as a useful links for a series of websites, a rough example of the code would be something like:
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
Process.Start("http://www.google.com");
}
private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
Process.Start("http://www.bing.com");
}
private void toolStripMenuItem3_Click(object sender, EventArgs e)
{
Process.Start("https://www.duckduckgo.com");
}
private void toolStripMenuItem4_Click(object sender, EventArgs e)
{
Process.Start("http://www.yahoo.com/");
}
...
Is there a more elegant way to handle this?
Put urls in menu items tag and attach this handler to all of them (hope it works)
private void toolStripMenuItemClick(object sender, EventArgs e)
{
Process.Start(sender.Tag.ToString());
}
The first thing to do is use the same handler for each one:
toolStripMenu1.Click += toolStripItemClick;
toolStripMenu2.Click += toolStripItemClick;
// etc
I would use the Tag property for this, set it when you're constructing the toolStripItems:
toolStripMenu1.Tag = "http://www.google.com";
And then define your handler:
private void toolStripItemClick(object sender, EventArgs e)
{
var c = (ToolStripMenuItem)sender;
Process.Start(c.Tag.ToString());
}
"Mash" all of the event handlers into one and then use the sender to see what ToolStripMenuItem was clicked.
private void toolStripMenuItem_Click(object sender, EventArgs e)
{
if(sender == toolStripMenuItem1)
Process.Start("http://www.google.com");
else if(sender == toolStripMenuItem2)
Process.Start("http://www.bing.com");
else if(sender == toolStripMenuItem3)
Process.Start("http://www.duckduckgo.com");
else if(sender == toolStripMenuItem4)
Process.Start("http://www.yahoo.com");
}
Or as Artem notes use the Tag member of the Control to store the String representing which site to visit. Then cast the sender.Tag to a String and use it.
toolStripMenuItem1.Tag = "http://www.google.com";
toolStripMenuItem2.Tag = "http://www.bing.com";
toolStripMenuItem3.Tag = "http://www.duckduckgo.com";
toolStripMenuItem4.Tag = "http://www.yahoo.com";
...
private void toolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start(sender.Tag.ToString());
}
You can also subscribe to click event using a lambda expression:
toolStripMenuItem1.Click += (_, __) => Process.Start("process1");
toolStripMenuItem2.Click += (_, __) => Process.Start("process2");

How can I switch between two methods in one button with every click?

I am new on C# so sorry if it look easy for some of you :)
I have this button click:
private void buttonSwitchCamera_Click(object sender, RoutedEventArgs e)
{
_blManager.SendTrackerCmd(TrackerCmdType.PrimaryAVT_ActiveSensor, (float)IR_Id.IR_1); // Switch to IR1
_blManager.SendTrackerCmd(TrackerCmdType.PrimaryAVT_ActiveSensor, (float)IR_Id.IR_2); // Switch to IR2
}
How can I switch between the two methods when clicking the button?
one click will be for method #1
second click will be for method #2
third click will be for method #1
etc..
You can do something like that:
bool executeMethodOne;
private void buttonSwitchCamera_Click(object sender, RoutedEventArgs e)
{
executeMethodOne = !executeMethodOne;
var IrId = executeMethodOne ? IR_Id.IR_1 : IR_Id.IR_2;
_blManager.SendTrackerCmd(TrackerCmdType.PrimaryAVT_ActiveSensor, (float)IrId);
}
Have a bool called executeMethodOne which you will invert everytime you click on the button. Depending on if it is true or false you can execute the first or the second method
First click is old:
private void OnButtonClickOdd(object sender, RoutedEventArgs e)
{
// Unsubscribe OnButtonClickOdd
button.Click -= OnButtonClickOdd;
// Subcribe to OnButtonClickEven
button.Click += OnButtonClickEven;
// Do your job here
}
private void OnButtonClickEven(object sender, RoutedEventArgs e)
{
// Unsubscribe OnButtonClickEven
button.Click -= OnButtonClickEven;
// Subcribe to OnButtonClickOdd
button.Click += OnButtonClickOdd;
// Do your job here
}
Other way: just use bool flag to know it odd or even click:
private bool odd = true;
private void buttonSwitchCamera_Click(object sender, RoutedEventArgs e)
{
if(old)
{
// Odd click job
}
else
{
// Even click job
}
old = !old;
}

Categories