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.
Related
I am trying to create plug-in that will catch any send item and show warning before sent out.
Currently I am using the below code
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Outlook.Application application = Globals.ThisAddIn.Application;
application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
However, I noticed it catches almost all the send event but when send button is pressed from main screen of Outlook, I mean when the mail is not popped out to separate window, it does not catch the event and my plugin function is not executed. My environment is Visual Studio 2019 and Outlook 2019. Any advise is appreciated.
Thank you,
Catch all the send event from Outlook.
Update 11/7/2022: it turned out that the event is caught but
I am tryning to catch the item type by the below method and inline item does not detected as an item.
itemtype = Application.ActiveWindow().CurrentItem.Class;
I can confirm that the ItemSend event is fired for all outgoing emails in Outlook, including inline responses. To make sure I've just created a sample VSTO add-in and placed your code there. Everything works correctly when I reply to items in-place. Try to declare the Application object at the class level. But I think everything should work as is now.
Outlook.Application application = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
application = Globals.ThisAddIn.Application;
application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
You may consider subscribing to the Explorer.InlineResponse event which is fired when the user performs an action that causes an inline response to appear in the Reading Pane. So, you may get the item composed and do whatever you need (subscribe to the Send event).
Be aware, a low level API such as Extended or Simple MAPI doesn't trigger the ItemSend event in Outlook - only actions made in the Outlook object model or made manually can trigger the event.
It should work in all cases, but Outlook disables most OOM events for the items created using Simple MAPI or from the "mailto:" links. Is that the case?
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.
I have few buttons in my windows application which has mnemonics.Now if i press multiple keys the events of the button clicks gets fired as i have used mnemonics.
But the behaviour is not as expected,because second button event handler is getting executed before the first button event handler has finished its execution,and also i have written my code in such a way that in the event handler of first button i am disabling my second button,still the second button event handler is getting executed.The problem here is due to mnemonics.PLease suggest me a better way to handle mnemonics as soon as possible.
Thanks in advance.
If your logic is tied to your buttons, change that. Let your buttons merely manipulations an object that implements your logic. You can then check in this object whether the requested action is allowed (i.e. whether the previous operation has finished.
Alternatively you can just disable buttons when running and re-enable then when.finished.
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.
I have a datetimepicker in C#. When I click on it, it expands to show a monthly calendar, when I click the left arrow to go back a month, it changes the value and calls my event. The event includes too much code to include here but it calls several functions needless to say.
The problem I'm having is that when I click that left arrow it gets stuck in some sort of loop and keeps descending through the months and I can't stop it. One of the functions that is being called contains a Application.DoEvents() and if I comment that out it doesn't get stuck in the loop, but I need that command to update another section of the interface. Any idea why this is happening?
I can duplicate it sometimes with this code, sometimes it just does it a couple times, sometimes it gets stuck in the loop.
private void DateTimePickerValueChangedEvent(object sender, EventArgs e)
{
afunction();
}
private void afunction()
{
listView1.Clear();
panel1.Visible = true;
Application.DoEvents();
}
I also have the same problem. In my case, instead of calling DoEvents I'm updating a Crystal Report view. The only workaround I found is to update my view upon the CloseUp event instead of ValueChanged or TextChanged.
Scott, how did you finally corrected your problem ?
The DateTimePicker ValueChanged event is buggy. Per Microsoft Windows Forms Team on this page https://connect.microsoft.com/VisualStudio/feedback/details/1290685/debugging-datetimepicker-event-hangs-vs:
"The DateTimePicker control installs a mouse hook as part of its functionality, but when the debugger has the WinForms application stopped on a breakpoint, it allows the possibility of a deadlock if VS happens to get a mouse message. For now, the deadlock is unfortunately a consequence of the DateTimePicker's design. The mouse hook is installed when the drop down is clicked to display the calendar. This means that breakpoints should not be sent in any event handlers which would be called while the calendar is active. We are currently investigating whether it is possible to address this issue and we will update this thread with further information if we are able to make a fix available."
Without seeing any of the code, try these steps:
Comment out the entire event handler
to see how fast it runs with nothing
attached to it.
Uncomment lines one at a time to see
which ones are causing the most
problems.
Analyze those method calls.
...
Profit!
You could try a couple of things. Get rid of the DoEvents inside of the ChangedEvent.
Call the doevents inside of a seperate function after maybe a period of time (thread.sleep() ?).
I know doevents does cause issues but I rarely use it.
event procedure ValueChanged :
set parameter in sender.tag
enableTimer and execute parameter using sender.tag
example:
private void DateTimePicker_ValueChanged(object sender, EventArgs e)
{
DateTimePicker ThisSender = (DateTimePicker)sender;
Timer.Tag = ThisSender.Name.ToString() + "=" + ThisSender.Value;
Timer.Enabled = true;
}