Dr. Dobb's Journal - August 2008 - (Page 39) Clipboard Operations Go back to the WPF Compound Documents sample application and insert some PhotoControls and TimeStampControls. Select content that includes these controls, right-click the selection, and select Copy. Then verify that the copied content can be pasted. The sample app is able to copy, cut, and paste UserControls by following this procedure when content is copied (see DocumentWindow.Copy). Before copying, the Name attributes of all UserControls in the selected content are extracted by a call to GetUserControlNames (Listing Two). Then PlaceholderControls are inserted into the empty BlockUIContainers and InlineUIContainers. The inserted PlaceholderControls have the same Name attribute value as the original UserControls. This modified XAML, containing the PlaceholderControls, is copied to the clipboard. Later, when users perfom a paste, the pasted PlaceholderControls is replaced with the original UserControls. (Listing One). Once it has found a PlaceholderControl, it calls the ControlFactory to create the real UserControl. It assigns a unique Name value to this control. Then it loads the control with data that was previously saved by calling the UserControl’s Load method. Before the data is loaded into the UserControl, it is cloned. This prevents one UserControl from modifying another UserControl’s data. When the document is printed, the print code calls IEnhancedUserControl.GetPrintMarkup() and renders the XAML returned by that method. This lets a UserControl have a totally different appearance when printed. For example, when the PhotoControl is printed, none of the buttons or checkboxes are displayed. Only the selected image appears on the printed page. The print files, DocumentPaginatorWrapper.cs and Print.cs, are based on code posted in Feng Yuan’s blog (see the source code for the URL). It’s easy to add your own custom UserControls. Just make sure your UserControl implements the IEnhancedUserControl interface. Also, add your control to EnhancedUserControlUtils.ControlFactory and EnhancedUserControlUtils.ControlTypeNames. As of WPF 3.5, the support for embedded GUIs in FlowDocuments is incomplete. This situation will likely improve in subsequent versions of .NET. In the meantime, you can use the techniques in this article to create full-fledged interactive GUIs that can be embedded in FlowDocuments. DDJ IEnhancedUserControl A UserControl usually has state that must be saved before converting it into a PlaceholderControl. The same state has to be loaded when PlaceholderControl is replaced by the original UserControl. For example, when a PhotoControl is converted to a Placeholder control, the image files selected by users must be saved, along with the Slideshow checkbox state, the width and height, and the number of seconds. That’s why the PhotoControl and TimeStampControl classes implement the IEnhancedUserControl interface: public interface IEnhancedUserControl { void Save(IEnhancedUserControl enhancedUserControl, string name, ICloneable dataToPersist); void Load(ICloneable dataToPersist); string GetPrintMarkup(); string Name { get; set; } } Figure 1: User Control Demo program. Listing Two // Get control names of all UserControls in the specified document // region. public static List GetUserControlNames(TextPointer start, TextPointer end) { List userControlNames = new List (); TextPointer current = start; // Scan through the document fragment while (current.CompareTo(end) < 0) { // If we encounter something that could potentially // contain a UserControl if (current.Parent is BlockUIContainer || current.Parent is InlineUIContainer) { // Get the BlockUIContainer or InlilneUIContainer's full // XAML markup. string containerMarkup = XamlWriter.Save(current.Parent); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(containerMarkup); // Extract the Name attribute from the XAML markup. XmlAttribute nameAttribute = xmlDocument.DocumentElement.FirstChild.Attributes["Name"]; string name = null; if (nameAttribute != null && !string.IsNullOrEmpty(nameAttribute.Value)) { name = nameAttribute.Value; } else { Debug.Assert(false); } // Store the UserControl's name in the List, avoiding // duplicates. if (!userControlNames.Contains(name)) { userControlNames.Add(name); } } current = current.GetNextContextPosition(LogicalDirection.Forward); } return userControlNames; } Because the sample app’s UserControls all implement this interface, the program can save each UserControl’s state, and restore it whenever necessary. To see the IEnhancedUserControl interface at work, take a look at EnhancedUserControlUtils.ReplacePlaceholdersWithRealControls August 2008 l www.ddj.com l Dr. Dobb’s Journal 39 http://www.ddj.com
Table of Contents Feed for the Digital Edition of Dr. Dobb's Journal - August 2008 Dr. Dobb's Journal - August 2008 Contents Friday Night Fish Fry Alia Vox Developer Diaries Developer’s Notebook A Conversation with Christos Papadimitriou OpenGL and Mobile Devices: Round 2 Ellipse Specification Using Vectors Embed Custom GUIs in WPF Building RIAs on J2EE Foundations Disentangling Concepts in Object-Oriented Systems The Agile Edge Effective Concurrency Swaine’s Flames Dr. Dobb's Journal - August 2008 Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page Cover1) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page Cover2) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 1) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 2) Dr. Dobb's Journal - August 2008 - Dr. Dobb's Journal - August 2008 (Page 3) Dr. Dobb's Journal - August 2008 - Contents (Page 4) Dr. Dobb's Journal - August 2008 - Contents (Page 5) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 6) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 7) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 8) Dr. Dobb's Journal - August 2008 - Friday Night Fish Fry (Page 9) Dr. Dobb's Journal - August 2008 - Alia Vox (Page 10) Dr. Dobb's Journal - August 2008 - Alia Vox (Page 11) Dr. Dobb's Journal - August 2008 - Developer Diaries (Page 12) Dr. Dobb's Journal - August 2008 - Developer Diaries (Page 13) Dr. Dobb's Journal - August 2008 - Developer’s Notebook (Page 14) Dr. Dobb's Journal - August 2008 - Developer’s Notebook (Page 15) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 16) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 17) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 18) Dr. Dobb's Journal - August 2008 - A Conversation with Christos Papadimitriou (Page 19) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 20) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 21) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 22) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 23) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 24) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 25) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 26) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 27) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 28) Dr. Dobb's Journal - August 2008 - OpenGL and Mobile Devices: Round 2 (Page 29) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 30) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 31) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 32) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 33) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 34) Dr. Dobb's Journal - August 2008 - Ellipse Specification Using Vectors (Page 35) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 36) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 37) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 38) Dr. Dobb's Journal - August 2008 - Embed Custom GUIs in WPF (Page 39) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 40) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 41) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 42) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 43) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 44) Dr. Dobb's Journal - August 2008 - Building RIAs on J2EE Foundations (Page 45) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 46) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 47) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 48) Dr. Dobb's Journal - August 2008 - Disentangling Concepts in Object-Oriented Systems (Page 49) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 50) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 51) Dr. Dobb's Journal - August 2008 - The Agile Edge (Page 52) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 53) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 54) Dr. Dobb's Journal - August 2008 - Effective Concurrency (Page 55) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page 56) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page Cover3) Dr. Dobb's Journal - August 2008 - Swaine’s Flames (Page Cover4)
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.