ToDo’s (from last post)
Need to figure out how to bind the NameValueCollection to the XAML for my WPF-based add-in. Then I need to find my a** with two hands and a map. And after that, perhaps I’ll look into the complexity of referral chasing to get the non-GC-replicated user attributes.
Bind AD Data to XAML
The more I look at this snarl of code I’ve pieced together from different samples, the more worried I get that I’ve created an intractable problem. I have three major classes developed so far (plus the XAML):
- ContextMenuItem.cs – inherits Office.IRibbonExtensibility, and implements the IRibbon extensibility member and the Ribbon callbacks (i.e. the context menu click handler). The click handler instantiates the Pop-Up window, converts the Outlook contact to an email address and runs the AD query.
- UserDetailsPopup.cs – implements the ElementHost WinForms object that wraps the WPF control.
- ActiveDirectoryUser.cs – implements the query against the Global Catalog, and returns a collection of requested data.
- UserDetailsLayout.xaml – implements the XAML UI in which we’d like to drop the requested data.
How should I store the data, and how can I get the XAML to consume it (and ensure it gets displayed in the UI)?
Where to Store the Data?
Let’s assume for the moment that the ContextMenuItem class gets instantiated when the user right-clicks on a contact, and doesn’t die until the context menu and/or the pop-up window it generates are all dead. That means any Property of the ContextMenuItem will exist during that timeframe, and can be read by other members of the add-in.
So exposing the data the add-in needs as a read-only Property of the ContextMenuItem class seems the only smart way to go here.
How to “Push” Data to UI?
Next, we need some way to cause something in the pop-up window (the XAML, the C# code-behind for the XAML, and/or the WinForms ElementHost that contains the WPF control) to consume the Property’s data, and then refresh the UI of the pop-up window if necessary.
I’m used to the fairly simple .NET app development model, where the first class instantiated is the UI, and it “pulls” in all code calls until the UI receives a callback (user click or some other event) that performs an atomic function. The best approach I can think of at the moment (given the classes I’ve constructed) is to create some function in either the UserDetailsPopup or the UserDetailsLayout (whichever’s code can cause the intended effect) that reads the ContextMenuItem’s property and then… what, “paints” the data into the XAML labels? Writes it to a class-local collection to which the XAML is already bound at design time? Or is there some other elegant feature of VSTO, WPF or .NET 4 that I am totally missing?
Here’s where my inexperience with (1) sophisticated design patterns or (2) WPF is coming to bite me on the butt. However, it occurs to me that the fundamental problem isn’t WPF but rather a VSTO-and-Outlook-centric design pattern that ferries remote data to local content-driven UI. Getting the data to the WinForms equivalent in this model must be the majority of the problem; pushing the data the last mile through the WinForms-to-WPF wrapper can’t be all that hard, can it?
So I guess my next quest is to find an Outlook VSTO code sample that creates a new WinForms object in response to user input (rather than all the examples that just graft VSTO code into an existing Outlook “Form” such as an email window, Appointment item and the like).
The final quest in making a functional object is to re-examine the WPF-in-ElementHost examples for Outlook VSTO add-ins, to see how external data gets bound or otherwise propagated into the XAML.