Sorry, we found 0 results. Please try another query.
Showing max 10 of results

Proxy Switcher erweitern

Wer Anwendungen nutzt, die aus irgendeinem Grund nicht auf die Internet Explorer Proxy Settings zurückgreifen können, der kann Proxy Switcher auch für beliebige weitere Anwendungen erweitern.

Dazu muss zunächst ein Class Library Projekt mit Visual Studio erstellt werden und eine Referenz auf ProxySwitcher.Shared.dll hinzugefügt werden. Das ganze funktioniert natürlich auch mit den kostenlosen Varianten Visual Studio 2005 Express Editions.

Nun einfach eine neue Klasse erstellen, die das Interface ISwitcher im Namespace ProxySwitcher.Shared implementiert. Die Methoden sind eigentlich selbst erklärend und müssen dementsprechend befüllt werden.

image

Die fertig kompilierte DLL dann nur noch in das ProxySwitcher “plugins” Verzeichnis kopieren und ProxySwitcher neu starten. Das neue Plugin steht nun im “Applications” Tab zur Auswahl zur Verfügung.

Demnächst gibts dann hier das Plugin (inkl Sourcecode) für meinen Lieblingsbrowser Opera.

Das Problem an Opera und an vielen anderen Produkten (Firefox, RSS Bandit, etc.) ist, dass man die Anwendungen neu starten muss, damit die neuen Proxy Einstellungen wirksam werden. Der Internet Explorer, bzw. Windows, bietet dafür eine API, mit der man Windows mitteilen kann, dass die Einstellungen aktualisiert wurden.

InfoPath Bug 2

Im Einsatz ist ein InfoPath 2003 Formular für einen länger dauernden Workflow. Das Dokument selbst wird dabei von jemandem erstellt, in einer SharePoint Document Library abgelegt und dann an einem anderen Tag von jemand anderem erneut aufgerufen (mit einer anderen View).

Problem ist, dass auf beiden Views innerhalb des Dokumentes zwei verschiedene Textfelder sind, die das Datum anzeigen sollen an dem das Dokument jeweils geöffnet wird. Dafür gibt es eine Funktion, nämlich today().

Das Problem ist, dass today() nun leider nicht heute, wie der Name sagt zurückliefert, sondern den Tag an dem das Formular *zum ersten Mal *geöffnet wurde… Bug oder Feature? Hätte man aber auch schneller drauf kommen können, wenn man mal bei Office Online nachliest:

Gibt das Datum als Daten vom Typ Datum (date) zurück, wenn das Formular zum ersten Mal geöffnet wird.

InfoPath Erweiterung: Multi-Select ListBox lädt Daten on-demand

Ein Kunde, der InfoPath 2003 einsetzt, hat einige Anforderungen, die sich nicht so einfach umsetzen lassen. Da das große weite Internet leider fast nichts dazu hergibt, hier meine Probleme inkl. Lösungen.

Anforderung 1: Eine “multi-select list box”, also eine ListBox zum anhaken. In InfoPath 2007 bereits enthalten, muss diese bei 2003 leider selbst gebaut werden. Dazu gab es einen recht guten Artikel bei InfoPathDev, den ich nun (nach deren umgestaltung) leider nicht mehr wieder finde… Deshalb hier nochmal in Kürze:

Die DataSource Struktur (der InternetPortals Knoten ist repeatable und “internetPortalSelected” ist vom Typ boolean):

image

Nun erstellt man eine optionale Section auf dem Formular, und bindet sie an den “PortalsGroup” Knoten. Innerhalb der optionalen Section erstellt man eine Scrolling Region. Dort zieht man dann den “InternetPortals” Knoten hinein und wählt “Repeating Table”. In den Eigenschaften hakt man “Allow users to insert and delete rows” und “Include Header” ab. Außerdem sollte die Tabelle natürlich keine Rahmen haben.

Jetzt nur noch das ganze entsprechend ansortieren, die Textbox durch ExpressionBox ersetzen und als default Wert für den Namen etwas schreiben wie “loading…”. Die ID muss dabei dem Benutzer gar nicht gezeigt werden und kann gelöscht werden. So sieht das ganze dann aus:

image

Anforderung 2: Und hier wird es komplizierter. Die ListBox soll nun mit Daten von einem WebService befüllt werden, und zwar erst beim öffnen der Section.
Problem 1 daran ist, dass es im IP 2003 Objektmodell keinerlei Events gibt, die ein aufklappen einer section anzeigen. Das einzige Event, was an der Stelle hilft ist das OnContextChange Event. Dieses wird allerdings ziemlich häufig gefeuert, z.b. bei jedem klick irgendwo auf das Formular, etc.

Problem 2 ist, dass man an die selbstgebaute ListBox keine DataSource anbinden kann (zumindest nicht über Wizards). Hier die Lösung (siehe Kommentare im Code): 

[InfoPathEventHandler(EventType = InfoPathEventType.OnContextChange)]
public void OnContextChange(DocContextChangeEvent e)
{
    if (e.Type == "ContextNode")
    {
        LoadPortals();
    }
}
 
private void LoadPortals()
{
    // Zunächst den Knoten finden der den Repeatable Knoten enthält
    IXMLDOMNode ipGroup = thisXDocument.DOM.selectSingleNode("my:Fields/my:PortalsGroup/my:Portals1");
 
    // Ist dieser null dann ist die section nicht aufgeklappt, es muss nichts getan werden
    if (ipGroup == null)
        return;
 
    // Die DataSource abrufen (hier: "GetInternetPortals"). Diese muss zunächst über
    // Tools->Data Connections angelegt werden und das häkchen bei "Automatically retrieve data
    // when form is opened" muss nicht selektiert werden, denn die Daten sollen ja nur bei Bedarf
    // geladen werden, um so das öffnen des Formulars nicht unnötig zu verlangsamen.
    DataObject dob = thisXDocument.DataObjects["GetInternetPortals"];
    dob.Query();
 
    // Hier müssen die Namespaces gesetzt werden um auf das DOM des WebServices zugreifen zu können.
    // Der erste Namespace ist IP 2003 standard, der zweite muss durch den Namespace
    // des WebServices ersetzt werden. 
    IXMLDOMDocument2 d = (IXMLDOMDocument2)dob.DOM;
    d.setProperty("SelectionNamespaces",
          "xmlns:dfs=[http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\](http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\)
           xmlns:tns="http://MY-WEB-SERVICE-URL.COM/SERVICES\"");
 
 
    // Den Knoten des WebService Response holen (wie dieser Knoten heißt lässt sich am einfachsten
    // raus finden, in dem man im debug modus einfach mal den Inhalt von d.xml anschaut).            
    IXMLDOMNode rootNode = d.selectSingleNode("dfs:myFields/dfs:dataFields/
                   tns:GetInternetPortalsResponse/tns:GetInternetPortalsResult");
 
    // Erst jetzt kann man feststellen, ob die Daten bereits in der Listbox enthalten sind
    if (ipGroup.childNodes.length > rootNode.childNodes.length)
        return;
 
    bool removeFirst = true;
 
    foreach (IXMLDOMNode node in rootNode.childNodes)
    {
        // Hier die beiden Knoten die vom WebService zurückgeliefert werden.
        string id = node.selectSingleNode("tns:Id").text;
        string name = node.selectSingleNode("tns:Name").text;
 
        IXMLDOMNode group = thisXDocument.DOM.
                 selectSingleNode("my:Fields/my:PortalsGroup/my:Portals1");
        IXMLDOMNode field = thisXDocument.DOM.
                 selectSingleNode("my:Fields/my:PortalsGroup/my:Portals1/my:InternetPortals");
        IXMLDOMNode newNode = field.cloneNode(true);
        if (removeFirst)
        {
            group.removeChild(field);
            removeFirst = false;
        }
        // Werte vom neuen Knoten setzen
        newNode.selectSingleNode("my:internetPortalId").text = id;
        newNode.selectSingleNode("my:internetPortal").text = name;
        group.appendChild(newNode);
    }
}

 

Demnächst mehr aus der InfoPath Hell...