I have a class which performs an async operation.
While that async operation (which works downloads a file) it should show a new dialog.
To close that dialog again and also show a progress in it, I made events that are fired and should let the event handlers do actions.
To show you that a bit clearer:
var dialog = new DownloadDialog();
DoAsyncDownload();
if (dialog.ShowDialog() == DialogResult.OK)
{
dialog.Close();
// Go on
}
So the download dialog is just there to show the user that a download is going on.
In order to show a progress and close the dialog then again, I want to work event-based.
What I made is an event:
public event EventHandler<EventArgs> DownloadFinished();
protected virtual void OnDownloadFinished(Object sender, EventArgs e)
{
if (DownloadFinished != null) DownloadFinished(sender, e);
}
Well, so in the method that is called async I call it like that, when the file is downloaded:
OnDownloadFinished();
Then this event is fired.
So, in order to make the dialog receieve this event I set an handler with the correct signature in the dialog's class.
Then I set this handler like that:
this.DownloadFinished += new EventHandler<EventArgs>(dialog.DownloadFinishedHandler);
But the event handler does never execute its code. :(
I checked this with breakpoints.
I think the problem is using a webclient to download the file. Its eventhandlers are not set at the right time I think.
The webclient is declared as a member outside any functions or anything, so that every function can access it.
Then the code in the method that is called async looks like that:
packageDownloader.DownloadFile(MyUrl, "Url");
OnPackageDownloadFinished(this, EventArgs.Empty);
Like I already said above, this functions is called then.
The same problem is appearing with the progress changed, it is the same.
The thing I am sure that there is any way this would work or the webclient is the guilty guy, is that I have already done the same thing with another method and there the eventhandlers are called and everything works fine. So in this other method another thing is done, but after that it also raises an event. And the handler set is exactly the same.
Only here it doesn't work, I think it is the webclient.
PS: If you have any questions or something isn't clear to you, ask me. ;)
The problem was very dumb. I didn't download the file asnyc, so no events could be raised that clear way.
Related
I am implementing Custom Task Panes with E-Mail Messages in Outlook.
The core is taken from this link MSDN (Walkthrough: Displaying Custom Task Panes with E-Mail Messages in Outlook)
Handler for property change is added:
void TaskPane_VisibleChanged(object sender, EventArgs e)
{
Globals.Ribbons[inspector].ManageTaskPaneRibbon
.toggleButton1.Checked = taskPane.Visible;
...some code here...
mailItem.PropertyChange += PropertyChangeHandler;
}
PropertyChangeHandler checks is recipients have changed and does some heavy routine with posts and so on. But... If I add 10 recipients and start to remove them with backspace PropertyChangeHandler stops firing at some point.
No errors. Buttons on custom task pane work fine.
What is wrong?
Seems that either event is eaten or inspector is incorrect, but I cannot spot problem and find the solution.
I also think that it might be about "heavy load" when next event is fired before previous is completed, but this is a guess
You need to call the Save method or save the message explicitly to make the PropertyChange event fired. Outlook caches values in the UI and doesn't propagate changes until the item is saved.
Also I'd suggest creating a log file (a regular text file) where you can write the debug statements. Thus, you will understand what happens in the code.
I know full path of file var temp_file = Path.Combine(_directoryName1, "temp.ini"); which need to be deleted in the end of program working. How could I do this ? As I know it is possible to realize via OncloseEvent(). In addition, I dont know exatly how user will close application via alt+f4 or via buttons.
So far, I have tried to use this code below from almost the same question How to override onclose event on WPF?
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//do my stuff before closing
base.OnClosing(e);
}
And I have added it in App.xaml.cs but it doesn't work. VS2013 says that he don't know such method base.OnClosing(e);
Is there any mistake or another way out?
Window.Closing is for a specific Window. That's probably not what you want in any case, because the Closing event can be cancelled. Window.Closed is likely a better choice.
To run something when the program is closed -- not tying yourself to a window -- you should subscribe to the Application.Exit event instead.
I have a button with an event handler attached to it; 2-clicking it in the designer takes me to the code. Nowhere is the handler being unhooked/detached.
Some code I expected to run apparently isn't, so I put a bunch of MessageBox.Show()s in the handler, even at the very beginning, but none of them display (Note: I can't step through the code; I have to do it this way (arggghhhh)).
Here's some of the code:
private void btnFind_Click(object sender, System.EventArgs e) // Find and list Records
{
MessageBox.Show("Made it into btnFind_Click 0"); //TODO: Remove after debugging
try
{
if (barcodeScanner != null)
{
// Turn off the listening
barcodeScanner.BarcodeScan -= new BarcodeScanner.BarcodeScanEventHandler(barcodeScanner_BarcodeScan);
}
MessageBox.Show("Made it into btnFind_Click 1"); //TODO: Remove after debugging . . .
What could be preventing this code from being executed?
UPDATE
Based on Mike C's idea, I added a MessageBox to the button_close handler. And when I click it, it does fire, but only after other code runs first; in this case, that other code doesn't prevent the Close_Click from (eventually) firing; with the Find button, though, it completely preempts it...IOW, I see the message from the Close button at the end when I click it, but I never see any of the messages in the Find button handler when I click it...
UPDATE 2
Oh my lanta/say it ain't so, Joe! What's happening is an event is being kicked off in the form's overloaded constructor, and somehow this event is always fired just then (after clicking the find button). The message I'm seeing, that preempts everything in the button event handler, takes place in a method which is called by processBarcode() which is called by processBarcode1(), which is invoked from barcodeScanner_BarcodeScan1(), which is called by barcodeScanner_BarcodeScan(), which is set up in frmEntry's overloaded constructor. If the previous coder had intended to drive me insane, he couldn't have done much better.
I guess there's a reason there's so much maintenance work "out there" or "out here": because there's so much bad broken code AND because the cats who make such a mess scratch a bunch of sand on it and walk away.
And this code is chock full of "huh?!?##$%^?!?" moments, where bizarre gyrations are not commented on at all, and yet there is this comment:
// Check connection
checkConnection();
The problem could be that the Click event of the button is not subscribed to properly. If there is no line resembling
this.btnFind.Click += new System.EventHandler(this.btnFind_Click);
in the Designer file of the form, that's it.
How can I register to event and do some actions at runtime?
For example when the user click on a button I want to register to OnMyEvent and run MyFunc that let's say initialize some textBox with the OnMyEvent args.
I'm using winforms and .NET 4.
EDIT
Maybe I was unclear... I need the ability to register to existing event and add a new method that will run when the event will fire. All at runtime.
EDIT2
i'll try to give an example...
lets say that i have a class named "A" that have many events OnDataRecived OnDataSend etc...
when the application running the user can choose form a combobox event name to register (i got the events list via reflection because they not constracts, they are generated from xml file) and which data to update when the choosed event is fired.
so for the example the user choose to register to the OnDataReceived and he choose to update property named DataStream. some code...
in run time upon user choosing:
A.OnDataReceived += (s,e) => MyRunTimeMethod(s,e);
private void MyRunTimeMethod(object sender, EventArgs e)
{
DataStream = e.Data.Value
}
You are asking how to create a method dynamically at runtime - once you have a reference to that method in a delegate, the question of how to register it to an event is trivial.
MSDN describes how to do this with MSIL instructions. I doubt that's what you're looking for, but it is an option.
The C# FAQ blog has a much more interesting solution using expression trees. I suppose this is the one you were referring to by originally tagging your post with expression-tree.
But I would reconsider using dynamic methods at all. How exactly is the user going to specify what action to perform on the event of his choice? I suspect that the options are limited enough that you can get by with something simpler:
protected void btnRegister_Click(object sender, EventArgs e) {
switch (cmbEvents.SelectedText) {
case "OnLoad":
MyControl.OnLoad += (s, e) => SomeSelectedControl.Text = SomeInputControl.Text;
break;
//... other cases
}
}
If you're using windows forms, double clicking a button will bring you to a created on_click event. If you bring up the properties window for the button, theres an events tab. Viewing this will show you which events are available for a control.
I found the best way to understand this, was to look at the code created when adding the events.
Update:
As noted, I completely missed the point with my answer. The syntax for subscribing to an event at runtime is the same way as it's done on form Initialize. So I don't get any terminology wrong, here's the link to the msdn documentation;
http://msdn.microsoft.com/en-us/library/ms366768.aspx
What you want to achieve, does not require you to "Register to event at run time".
If button1 is the button of interest here, simply use.
button1.Click += buton1_ClickHandler;
button1_ClickHandler should be defined in the same class as your button1. and it should have the signature of the RoutedEventHandler. So, it should be
private void button1_ClickHandler(object sender, RoutedEventArgs e)
{
//method code here
}
E.g. instead of having a button to initiate the method, the method automatically happens without any user interaction - automatically.
private void button13_Click(object sender, EventArgs e)
{
try
{
ServiceController sc = new ServiceController();
sc.ServiceName = "Spooler";
if (sc.Status.ToString().ToLower() == "stopped")
{
serviceStatusLabel.Text = "Installed but stopped";
}
if (sc.Status.ToString().ToLower() == "running")
{
serviceStatusLabel.Text = "Installed and started";
}
}
catch
{
serviceStatusLabel.Text = "Service not installed";
}
}
I just want the Label object to show the service status when the form is loaded up, without using a button
EDIT: Given your comment, are you actually after the Form.Load event? It sounds like it. Any event handlers subscribed to that event will be executed "when the form is displayed for the first time".
(The confusing thing is that your title talks about "On-Load" of an object whereas it sounds like you really want the method to be called when the form is loaded.)
It's not really clear what you mean by "when its output on the form" but you might want to look at the TextChanged and VisibleChanged events. That's if you want something to happen when the label is altered.
If you're looking for when the service status is altered, it doesn't look like there's an event raised for that, I'm afraid. Note that it would be much cleaner to switch on the enum value rather than to convert it to a string, lower it, and then compare that with hard-coded constants.
... Do I get your question correctly?
You want a piece of code to be executed when an object or the form is loaded?
Well that's easy :p
Click on your object (or form) in the designer, in the properties dock, click the lightning bolt icon, go to the Load or Show event, and double-click the box.
A new piece of code should now be created in the code view, something like this:
private void Object_Load(blabla) handles Object.Load
{
}
Whatever code is in that event will be executed when the object is loaded or shown.
If you create a handler for the Load event, it will run when the form gets loaded.