MSDN Magazine - December 2007 - (Page 60) place it with a new method, called GetDefinition, that takes a keyword string and returns a string of XML data: [ServiceContract()] public interface IImageService { [OperationContract] string GetDefinition(string myValue); } The WPF UserControl There are two obvious ways you can use WPF in an application: to enhance the user interface and to provide sophisticated data visualization. My example focuses on the rich UI capabilities. The important point here is how easily you can incorporate WPF controls in VSTO solutions. I could demonstrate that with an extremely simple WPF control—perhaps a grid with a button on it—but it would be a shame not to take advantage of the sophisticated graphics capabilities of WPF, so I’ll use a custom WPF UserControl that provides a fish-eye animation behavior. I’ve based it on the HyperBar sample for Microsoft Expression Blend™ (available at blogs.msdn.com/expression/articles/516599.aspx). It’s also based on Paul Tallett’s FishEyePanel described at codeproj ect.com/WPF/Panels.asp. The major difference I’ll introduce is to put the WPF control in a non-WPF window so you can see it hosted in a native Office window. To begin, I’ll create a Windows WPF UserControl Library project—this produces some starter XAML and the corresponding C# codebehind. The first thing to do is change the UserControl class name from UserControl1 to something more meaningful— FishEyeControl. This FishEyeControl will contain a collection of buttons managed by a custom panel, named FishEyePanel, which derives from System.Windows.Controls.Panel. In FishEyePanel, I set up event handlers for three mouse events (MouseMove, MouseEnter, MouseLeave) so I can invalidate the panel and cause it to be re-rendered whenever the user moves the mouse over it. Here is one of the mouse event handlers: public class FishEyePanel : Panel { public FishEyePanel() { this.MouseMove += new MouseEventHandler(FishEyePanel_MouseMove); } private void FishEyePanel_MouseMove(object sender, MouseEventArgs e) { this.InvalidateArrange(); } I could get the XML data from anywhere; realistically, the WCF service would be running on a server and could perhaps source its data from a server-side database or some line-ofYou can use WPF in an business (LOB) system application to enhance such as SAP or Siebel. In my sample, however, I will the user interface and to run the service on the loprovide sophisticated data cal machine and source visualization. the data from a static XML string resource. The XML data source I’ll create will contain a number of item elements, each of which represents a simple mapping of a keyword to a definition: Frangipani Some description goes here. Toucan …etc If I add this XML data file to the project resources, I can implement the service constructor to load the XML data from resources. Then, I can implement the GetDefinition contract method to return the item that matches the keyword the user requested. At the same time, I echo the return string to the console window. Note that the sample code is simplified and does not include the exception handling you would normally incorporate: public string GetDefinition(string keyword) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Properties.Resources.ImageData); String xPath = String.Format( “descendant::Item[Key=’{0}’]”, keyword); XmlNode node = xmlDoc.DocumentElement.SelectSingleNode(xPath); String nodeXml = node.OuterXml; Console.WriteLine(nodeXml); return nodeXml; } } To connect the FishEyePanel to the FishEyeControl, I had to set up the ItemsControl property on the FishEyeControl, like so: Next, the console application simply needs to start and stop the service. static void Main(string[] args) { ServiceHost s = new ServiceHost(typeof(ImageService)); s.Open(); Console.WriteLine(“press ENTER to stop the service”); Console.ReadLine(); s.Close(); } With the service now defined, implemented, and configured, I can build this piece of the solution and start it running. I’ve set it up so that the service runs in the console application, waiting for incoming calls, until the user presses Enter in the console window. 60 msdnmagazine Office Services Next, I set up some data resources for the panel. Instead of trying to set up a more realistic Web service or LOB data source, I’ll just use local files as resources. In this sample, I’ll use a simple list of .jpg files as the images on the buttons. These JPGs are in external files, so I need a little code to take the simple file name (such as Frangipani.jpg) and convert it to a fully qualified path that will be valid at run time. For this, I can define an implementation of http://blogs.msdn.com/expression/articles/516599.aspx http://www.codeproject.com/WPF/Panels.asp http://www.codeproject.com/WPF/Panels.asp
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.