Welcome to X4U
Minimize 

Hello visitor.

This is the personal homepage of Helmut Obertanner.
I'm a computer freak and electronic enthusiast and I live in Munich in Germany - the hometown of the famous Oktoberfest.
Why the name X4U? In my case it's a synonym for everything is possible.
I'm an experienced full time C# developer and doing so since .Net Framework 1.0.
As technical enthusiast I started Office development using .Net technologies.
As I searched answers and found help in the Internet I decided to share my knowledge in newsgroups and forums too. For participation, helping other developers, writing how-to's and articles and doing consulting and trainings I received the Microsoft MVP Award for the 3rd time.

As Outlook C# specialist I founded the website Outlooksharp.de
Beside software development, I'm building electronic devices for customers.
Prototypes with SMD PCBs and complete electronic devices with USB connections are my typical portfolio.
You got an Idea and have no plan how to put it to work - give me a call and I tell you if I can help.
A complete solution starts from defining the requirements, design the schematic and PCB, build a functional prototype, program the firmware, program the windows software, design and build a housing prototype.
Usually I work with very cheap PIC 18F Microcontrollers, these multifunctional devices are programmed in C language. 

I'm located in Germany with satisfied customers around the globe.
Enjoy the content of my site and feel free to give me your feedback.
You're welcome.
X4U Blog
 
Jan8

Written by:Helmut Obertanner
1/8/2010 9:06 PM 

In diesem Beispiel möchte ich über meine Erfahrungen zum über das Schliessen eines Formulars per Programmcode berichten.

Vor kurzem habe ich ein Beispiel zum Überprüfen und Absichern von Geschäftsregeln in einem Outlook Add-in berichtet:
http://www.outlooksharp.de/Home/tabid/36/EntryId/54/Geschaftsregeln-fur-Outlook-Formulare.aspx

Das Problem:

Implementiert man eine Lösung zum Sicherstellen von Geschäftsregeln möchte man den Benutzer darauf hinweisen, dass irgendetwas nicht korrekt ausgefüllt ist. Dazu kann man dem Benutzer einen modalen Dialog(MessageBox) anzeigen. Ist eine der Regeln ungültig, kann der Benutzer weder speichern – noch das Formular schliessen. Man sollte dem Benutzer aber immer die Möglichkeit geben einen Vorgang abzubrechen. Zu diesem Zweck kann man dem Benutzer im der Close-Benachrichtigung einen Dialog mit zwei Schaltflächen anzeigen z.B. Ok und Abbrechen. Klickt der benutzer in diesem Fall auf Abbrechen – soll das Formular einfach geschlossen werden ohne die modifizierten Daten zu speichern.
Prinzipiell sieht die Lösung wie folgt aus:

///<summary>

/// Flag is used to close the Form when Cancel is clicked

///</summary>

bool _closeAfterCancel = false;

 

///<summary>

/// Validates the BusinessRules and returns true if all rules are valid

///</summary>

///<param name="showCancelButton">If true, a OK/Cancel MessageBox is displayed to the user</param>

///<returns>true when all rules are valid</returns>

publicbool Validate(bool showCancelButton) {

 

if (Item.Saved) returntrue;

 

// Default value

_closeAfterCancel = false;

 

// if every business rule is valid we return true

if (_BusinessRules.TrueForAll(X4UBusinessRule.IsRuleValid)) returntrue;

 

// no ?

// show a warning to the user and

StringBuilder message = newStringBuilder(500);

message.AppendLine("You can't save this Item, because the following requirements are not met:");

foreach (X4UBusinessRule rule in _BusinessRules) {

if (!rule.IsValid()) message.AppendLine(rule.Description);

}

 

// display a message to the user what's wrong.

DialogResult messageBoxResult = MessageBox.Show (newOutlookWin32Window(Inspector),

message.ToString(), // Message

"Warning!", // Caption

showCancelButton ? MessageBoxButtons.OKCancel :MessageBoxButtons.OK, // Which Buttons should we display

MessageBoxIcon.Exclamation, // The Icon

MessageBoxDefaultButton.Button1 // The Default Button

);

 

// when OK-Button is clicked, we cancel the Operation

if (showCancelButton && messageBoxResult==DialogResult.Cancel ){

_closeAfterCancel = true;

}

 

returnfalse;

}

Wenn eine der geschäftsregeln nicht eingehalten wird, liefert die Validate-Methode false zurück.
Klickt der Benutzer auf die Abbrechen-Schaltfläche im angezeigten Dialog, soll das Formular ohne die Daten zu speichern geschlossen werden.
Um das zu erreichen wird ein Flag_closeAfterCancel auf true gesetzt. Normalerweise könnte man jetzt einfach die Methode Inspector.Close(Outlook.OlInspectorClose.OlDiscard) im Item_Close event aufrufen.

///<summary>

/// This Method is called when the Item is going to be closed

///</summary>

///<param name="Cancel"></param>

void Item_Close(refbool Cancel) {

if (!_closeAfterCancel) {

Cancel = !Validate(true); // MessageBox with OK + Cancel Button

if (_closeAfterCancel) {

Inspector.Close(Outlook.OlInspectorClose.olDiscard);

}

}

}

Leider musste ich feststellen, dass dies so nicht funktioniert. Anstatt das Formular zu schliessen, wird ein "Möchten Sie die Änderungen Speichern"-Dialog angezeigt.
Außerdem wurden im Outlook Objekt Model(OOM) einige Änderungen durchgeführt, welche eine korrekte Funktion verschiedener Methoden im Close-Event verhindern, siehe KB929593.
Als Lösungsansatz kann man einen Timer starten und im Timer_Tick event die Methode Inspector.Close aufrufen.
So sieht der modifizierte Programmcode dazu aus:

///<summary>

/// Used to call Close() out of the Item_Close event.

///</summary>

Timer _closeTimer;

 

///<summary>

/// This Method is called when the Item is going to be closed

///</summary>

///<param name="Cancel"></param>

void Item_Close(refbool Cancel) {

if (!_closeAfterCancel) {

Cancel = !Validate(true); // MessageBox with OK + Cancel Button

if (_closeAfterCancel) {

_closeTimer = newTimer();

_closeTimer.Tick += newEventHandler(_closeTimer_Tick);

_closeTimer.Start();

}

}

}

 

void _closeTimer_Tick(object sender, EventArgs e) {

_closeTimer.Stop();

_closeTimer.Dispose();

 

// Close the current Form without saving

Inspector.Close(Outlook.OlInspectorClose.olDiscard);

}

Jedoch wenn man dies ausführt kommt folgendes Resultat:

  • Es wird kein "Möchten Sie die Änderungen Speichern"-Dialog angezeigt
  • Das Formular wird geschlossen
  • Die Daten werden gespeichert

Es funktioniert einfach nicht wie gewünscht.
Nach meinen Erkenntnissen ist die einzig funktionierene Form anstatt der Inspector.Close(olDiscard)- die Item.Close(olDiscard)-Mehtode aufzurufen.
Der korrekte Code sieht dementsprechend aus:

void _closeTimer_Tick(object sender, EventArgs e) {

_closeTimer.Stop();

_closeTimer.Dispose();

 

// Close the current Form without saving

Item.Close(Outlook.OlInspectorClose.olDiscard);

}

Nur mit dieser Implementierung wird das Formular geschlossen ohne die Daten zu speichern.

Herzlichen Dank an Ken Slovak, durch Ihn bin ich auf die korrekte Lösung gekommen.

Viele Grüße – Helmut Obertanner
http://www.x4u.de

Tags:

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment  Cancel 
X4U Blog
 
Home  |  Hardware  |  Software  |  Services  |  Resources  |  Impressum