Footnote

Preface

[1] This code name has no relationship to the Ruby programming language.

Chapter 1

[1] As programs become more complex, the differences between WPF and Windows Forms become more apparent.

[2] This is similar to the Visual Basic “default property” feature.

[3] We can do this by adding System.Windows.Markup.ContentPropertyAttribute to the type.

[4] After this chapter, I will omit the “…/xaml/presentation” and “…/xaml” namespaces from markup samples. I will consistently map the presentation (WPF) namespace to be the default XML namespace, and “x” as the prefix for the XAML namespace.

[5] We will see later that even in navigation scenarios a window is created for page-based applications.

[6] The naming convention for code-behind files is “<markupfile>.cs”, so for mywindow.xaml we would create a file called mywindow.xaml.cs.

[7] Chapter 2 will explain why this step is required.

[8] The .NET Framework 3.0 redistributable is available at http://msdn.microsoft.com/windowsvista/downloads/products/default.aspx.

[9] The Windows SDK is available at http://msdn.microsoft.com/windowsvista.

[10] Visual C# Express is available at http://msdn.microsoft.com/vstudio/express/visualCsharp/default.aspx.

[11] Reflector is available at http://www.aisto.com/roeder/dotnet.

Chapter 2

[1] The manifests for the project must also be signed, so SignManifests, ManifestKeyFile, and ManifestCertificateThumbprint must be included in the project file. The best way to enable signing is to check the SignManifests button on the Signing tab in Visual Studio’s project properties view. It is unfortunate that browser-hosted applications require this complexity.

[2] XBAPs normally run with “Internet” security, so they are limited in functionality to operations that are safe for partially trusted code.

[3] I say “temporarily deployed” because browser applications have no permanent presence on the local machine. They are actually deployed to the client, but put into a cache that will be purged just like the Internet Explorer cache.

[4] The [STAThread] marker on the entry-point function is required. Like Windows Forms and User32 before it, WPF requires the UI thread to be STA (single-threaded apartment) because many components that WPF uses (such as the Clipboard) require STA. To ensure consistent behavior, the WPF team decided to make STA a requirement at all times.

[5] To be explicit, Run starts the dispatcher, which is responsible for sending events and messages. The dispatcher is covered in more detail in the appendix.

[6] As we’ll see later, Application is the only markup item that doesn’t require a call to InitializeComponent.

[7] The CLR provides a mechanism—the constrained execution region (CER)—that guarantees execution even when no memory is available. Code in a CER must not allocate memory, box values, or call methods that are not also part of a CER. The burden of writing CER code is extremely high, so CER code is generally reserved for only the deepest layers of the platform (fewer than a hundred methods in all of .NET use CER). WPF instead relies on memory gates that cause the system to fail with a recoverable exception before the system completely runs out of resources. Memory gates are predictive (evaluating system resources and failing before no memory is available), and as such they cannot guarantee success. The goal of memory gates is to reduce the likelihood of hitting a hard out-of-memory condition. Although we do everything we can to avoid these unrecoverable exceptions, they aren’t as interesting; they are unrecoverable, and the process will simply terminate if any of these arise.

[8] Dispatcher here refers to the top-level messaging-handling object, which is the object that does the work inside of Application.Run.

[9] Or using Visual Studio .NET’s Solution Explorer.

[10] Several other options—for example, ApplicationDefinition, Compile, or Page—don’t relate to resources.

[11] Resource and EmbeddedResource support localized loading. We can create specially named assemblies with alternate versions of the resources. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcreatingusingresources.asp for more details.

[12] To be 100 percent correct, the image was embedded into the assembly’s resource section. This is often called a manifest resource because these resources appear in the assembly manifest.

[13] There is a Window.Deactivated event as well, which is raised when the window ceases to be the focused window—typically during phase 6 in this list.

[14] Modality is a fancy word for describing a window’s behavior with respect to other windows in the application. Windows that block all other windows are said to be modal. When a modal window is displayed, the window must be closed before the user can interact with any other window. Modeless windows are the opposite: they do not block other windows, and therefore the user can interact with any window while any number of other modeless windows are displayed.

[15] It is important not to confuse history with the journal. The Internet Explorer team refers to the two concepts as History and TravelLog, respectively. History is a persistent list of sites visited, a type of automatic bookmark list created on the basis of time. The journal, or TravelLog, is the list of sites visited in this session. This is a subtle difference, but it’s important when we’re thinking about a navigation framework.

[16] All this code of blocks and inlines will be explained in more detail in Chapter 5. For now you’ll have to trust me when I say that this is adding a couple bits of text with a hyperlink.

[17] Notice also that we had to unhook from LoadCompleted in our handler. LoadCompleted is a NavigationService event; that is, it will fire for every page that is loaded in NavigationService. By unhooking after we are notified of the page being loaded, we avoid getting extra notifications. It is also important to unhook from the event to prevent NavigationService from keeping our page in memory for the lifetime of the service.

[18] For an example, see http://blog.simplegeek.com/book.

[19] There is no complete list of functionality available in partial trust; rather, the SDK documentation for .NET Framework 3.0 states whether each function is available in partial trust.

[20] Complete information on ClickOnce application manifests is included in the WinFX SDK.

[21] Complete information about ClickOnce deployment manifests is included in the WinFX SDK.

[22] Astute readers might notice that the download size of this application is huge (30MB). In reality, the compiled application is so small that I couldn’t get a screen capture of the download dialog. To make this picture I added a bunch of junk data to the program to make it take a few seconds to download.

[23] There is a very subtle, but important detail about the security ramifications of how PresentationHost is run. On Windows XP, presentationhost.exe is launched with modified NT permissions; effectively we strip the admin token off whatever permission iexplore.exe is running with. This provides an additional security level on top of the CLR code access security model. On Windows Vista, the Limited User Access feature provides this same type of security model globally for all applications running on the system.

Chapter 3

[1] Data templates will be covered in Chapter 6.

[2] It seems there’s always an exception.

[3] Originally the WPF team toyed with the idea of naming the ButtonBase class System.Windows.Controls.Clickable, but then we thought better of it!

[4] Interestingly, WPF controls change the keyboard accelerator notation from “&” to “_”. So if we wanted a button with the content “OK” and wanted “O” to be the accelerator, we would specify <Button>_OK</Button>. This change was introduced primarily because the XML rules around “&” would have required a very verbose “&amp;” to be used everywhere an accelerator was needed.

[5] Well, as close as possible.

[6] The default template for ListBox uses ItemsPresenter, which works as an item host by default, and honors the ItemsPanel property on ListBox.

[7] Gestures are a Tablet PC concept that converts a pen “gesture” (like making a check mark, or drawing a circle) into a programmatic command (like “check” or “circle”). Gesture recognition is a type of handwriting recognition.

[8] TextRange can also be used to save and load sections of rich formatting. Using TextRange.Save, we can write out all or part of a document as RTF or XAML. Using TextRange.Load, we can read all or part of a document as RTF or XAML.

[9] If we move left through the text, we see different numbers. Why? Because of a concept called gravity. The system tries to guess the element into which we want to insert text. If the caret is currently between c and d and we move to the right, we probably want to insert text into the boldface element. However, if the caret is between the e and f and we move left, we probably want to insert the text into the nonboldface element. This idea of gravity is common in text editors, and for users typing into the editor it normally “just works.”

[10] You don’t need a Tablet PC to try this example. By default, WPF will let a mouse act as a pen on InkCanvas. Mice today don’t send pressure data, so the lines will be of uniform thickness, but hey, you could always convince your boss to buy you a Tablet, right?

[11] In fact, the outermost window display (the title bar, minimize and maximize buttons, etc.) are not accessible via any API in WPF. To customize the outermost part of the window (or receive events from it), we must either use P/Invoke or turn off the default window display (WindowStyle.None) and draw our own borders.

Chapter 4

[1] This chapter omits one large component of layout: text. Text layout presents an interesting set of challenges around pagination, columns, and reading optimizations (like hyphenation and justification). Text layout is implemented as just another extension of the base layout model. It is covered in detail in Chapter 5.

[2] The problems with creating a single engine are varied. Pagination is one of the most obvious examples. In a document-focused layout engine, all components must be aware of pagination (the idea that something can be broken across page boundaries). Pagination introduces a large amount of complexity into every control, making it very difficult to create controls that behave correctly in all situations. As a result, systems tend to create a closed set of things that can be paginated, and then everything else is treated as a black box that cannot be split across pages.

[3] The rationale for the two sets of methods is to separate the method that we override to implement layout (ArrangeCore and MeasureCore) from the methods that can be called publicly (Arrange and Measure). For example, in the implementation of a layout panel, Arrange and Measure should always be called on the children; ArrangeCore and MeasureCore should never be called directly. This separation was created to allow the system to perform work (like caching, or updating the display) during the measure and arrange phases.

[4] 3D layout is a very interesting problem space; at this time, however, it is a problem best left to researchers.

[5] A smaller debate focused on how to deal with physical units (inches, centimeters, etc.). Because all lengths in WPF are 1/96 inch, however, trivial math can be used to support any units desired.

[6] The value Double.NaN can also be used.

[7] It’s a bit of a misnomer to talk about “before” and “after” with rendering. Because WPF is a retained-mode system we are actually talking about before and after with respect to generating the list of drawing instructions. RenderTransform introduces the transform into the drawing instruction list but never tells the layout system about that transform. LayoutTransform puts the same transform in the drawing instruction list but also applies that transform to the measure calculation for the control.

[8] Remember that we talked about Measure/Arrange versus MeasureCore/ArrangeCore, and how indirect use of the latter provides the system the ability to implement features around the measure and arrange phases. In the case of FrameworkElement, we wanted to add a lot more features (slot model, etc.). By overriding the “core” methods and providing new entry points, a developer can derive from FrameworkElement, override MeasureOverride and ArrangeOverride, and ignore the rest of these layout features.

[9] Notice that we’re using the InternalChildren property; this property is intended for layout authors. The InternalChildren property is required if you intend to use the panel inside of an ItemsControl object or in another context that generates children (we’ll talk more about this in Chapter 6).

[10] The only other feature related to custom layout that is worth mentioning is having layout that depends on a property (or set of properties) like DockPanel.Dock. When defining custom properties, we can specify that they affect arrange, measure, and render. This topic is covered in more depth in the appendix.

Chapter 5

[1] Visual Basic uses a system called twips, which is based on the typographic unit of points. Points are roughly defined as 1/72 of an inch, and a twip is 1/20 of a point or 1/1440 of an inch.

[2] The original Macintosh monitors were 72 dpi, to make them line up with the point measurement.

[3] Today the typography point is treated as exactly 1/72 of an inch on most computer-based typesetting applications, even though the original point was slightly smaller.

[4] The s is for standard, RGB for red-green-blue. This color model is documented by the W3C (World Wide Web Consortium) at: www.w3.org/Graphics/Color/sRGB.

[5] Gamut refers to the number of colors that can be expressed. There’s a gamut that the human eye can perceive, there’s a gamut that a display device can produce, and there’s a gamut that a color encoding can represent. Saying that something has a “compact gamut” means that it can represent only a small spectrum of all possible colors.

[6] The typical grading scale used in schools provides another example of gamut. This scale has a gamut of A through F, with only five distinct values: A, B, C, D, F. We can increase the precision of this scale by adding more values: A, A–, B+, B, B–, and so on. We can also increase the gamut, the actual range of possible values, by adding A+ or F–. By increasing the gamut, we can capture grades outside the bounds of A–F.

[7] The origin of the sc in scRGB is shrouded in mystery. Officially it stands for nothing. According to Michael Stokes (the national and international leader of the International Electrotechnical Commission, or IEC, group working on scRGB), the name appeared when the Japanese national committee requested a name change from the earlier XsRGB (excess RGB). The two leading candidates for meaning are “specular RGB” because scRGB supports whites greater than the diffuse 1.0 values, and “standard compositing RGB” because the linearity, floating-point support, HDR (high dynamic range) support, and wide gamut support are ideally suited for compositing. This meaning also implicitly emphasizes that scRGB is not intended to be directly supported in devices or formats, since by definition scRGB encompasses values that are beyond both the human visual system and (even theoretically) realizable physical devices.

[8] The International Color Consortium (www.color.org) defines a common format for color profiles.

[9] Interestingly, because ImageBrush can take a drawing image as the source, we can use either ImageBrush or DrawingBrush to fill something with a drawing.

[10] Flat and square dash caps look remarkably similar. Comparing the flat and square line caps in Figure 5.16 shows that, as the pen thickness increases, the cap becomes large (effectively making square line caps extend past the last point of the line). The same phenomenon occurs with dash caps: Square dash caps make the dash slightly longer than the flat version. In practice, it is remarkably difficult to tell the difference between the two.

[11] To be clear, the inefficiency isn’t really the poor Image control’s fault. Because the image may be resized at runtime by the layout, we can’t determine the right size for decoding the image. One option would have been to reload the image whenever the display size grew, but that would have introduced lags and jumps as the control was resized. Instead we opted to add DecodePixelWidth and DecodePixelHeight to BitmapImage so that application developers could easily optimize efficiency.

[12] Don’t confuse these with frames from HTML, video, or anything else. Each frame in the raster image model is simply a single image. Actually, it would make some sense to confuse this with a video frame because logically video is just a lot of raster image frames.

[13] The size passed into SourceRect depends on the image we provide. In this case, the original was an 800×533 pixel image.

[14] BeginInit and EndInit are part of the ISupportInitialize interface defined in .NET 1.0. Normally these methods are optional to call, but with WPF imaging they are required.

[15] We can build new bitmap effects in managed or unmanaged code; at this time, however, we cannot create new effects that run directly on the graphics hardware (maybe in a future version of WPF).

[16] Remember that the camera orientation drastically affects the display. In this case, we are assuming that a positive y value indicates “up.” Figure 5.33 shows that z values indicate a direction away from the camera.

[17] WPF uses the right-hand rule for determining the face of a triangle. To understand this rule, curve your right hand around with your thumb pointing up. When you specify the coordinates along the direction of your fingers, the normal of the surface is in the direction of your thumb. Another way to think about this is that, when you’re facing a surface, the triangle vertices must be ordered counterclockwise.

[18] Available online at www.poynterextra.org/msfonts/osprey.doc.

[19] Originally Unicode was strictly a 16-bit system. There are lots of alternative encodings of the 16-bit values for Unicode, however; one of the more common is UTF-8, which uses 8 bits for the most common values in Western languages. The more recent Unicode specs now contain characters that require two 16-bit values. It is more correct to say that Unicode is a specification of how to represent characters.

[20] If you’re curious how to type this, install the Japanese language pack for Windows XP. Then install the IME (input method editor) for Japanese, which will let you type Japanese on a keyboard.

[21] A typeface is basically a program that renders text. It may sound strange, but fonts are a lot like CLR IL (Common Language Runtime Intermediate Language) programs. Each typeface is a specially authored version of the general font for a specific style.

[22] In XAML, all family names are listed in the same way: <Button  FontFamily=’Arial,  Tahoma’/>.

[23] Padding is an odd term to use; typically this feature would be called margins, but we consistently use padding to describe insets.

[24] You may notice as you dig through the various types in the System.Windows.Media namespace that they sometimes have common patterns, but not common base types. To build all the strongly typed collections, animations, and other patterns, the WPF team used a code generation template. This common template (which isn’t visible in the actual product) is what ensures that all animations have the same properties and methods, even though they are defined independently.

[25] Although we can animate any property type, only properties implemented by the DependencyProperty system can be animated.

Chapter 6

[1] The only case in which the WPF development team decided not to support transformation with a binding was resources. The rationale for this decision was that resources are defined in the domain of the presentation, so there is no need for further transformation.

[2] Specifically, anything deriving from FrameworkElement, FrameworkContentElement, or Application has a Resources property.

[3] Freezable objects support sharing by having a “frozen” mode, in which they cannot be changed. The frozen mode allows for a single instance to be used by multiple objects, without consumers having to watch for changes in the object.

[4] Be very careful that the dependency property you’re passing is defined on the same type as the object from which SetBinding is called. For example, if you call SetBinding with TextBlock.TextProperty instead of TextBox.TextProperty when binding against TextBox, your code will compile and run just fine, except that the binding will not work.

[5] For example, if we wanted to bind to the Grid.Row property from a TextBox object, we would say, <SomeControl  SomeProperty=’{Binding  ElementName=text1,  Path=(Grid.Row)}’  />.

[6] For the more adventurous, it is possible to use ICustomTypeDescriptor to enable WPF binding to work against any specialty object model. In combination with the .NET 2.0 TypeDescriptorProvider feature, existing specialty object models can work seamlessly with WPF binding. Implementing ICustomTypeDescriptor is, alas, beyond the scope of this book.

[7] If you’re curious, the try/catch method around the implementation is to (poorly) handle the cases in which we are denied access to directories that we don’t have permission to access.

Chapter 7

[1] The routed-event system is the part of WPF that is responsible for routing events through the element tree. This system is mostly hidden, with only small parts of it, like EventManager.RegisterRoutedEvent, visible.

[2] The common reason for creating a custom version of command routing is that a route is not tied to the element tree. It’s very easy to imagine a system with a document and project structure in which we would want the command route to follow the logical structure, not the display tree.

[3] Input gestures include mouse, keyboard, and stylus input. Input gestures are covered in detail in the appendix.

[4] This example should not be misinterpreted as a secure way to implement filtering. Any filtering done on file extension is very easy to spoof. I just wanted a simple example, instead of actually trying to sniff the bytes or doing something really secure.

[5] Don’t let the Triggers properties on FrameworkElement and FrameworkContentElement fool you. They are like the appendix in the human body: They have very little value and can be removed if they start causing problems. In all seriousness, triggers are implemented through the property system and work only in templates and styles. The local Triggers property is there as a placeholder, and hopefully will work directly in a future release of WPF.

Chapter 8

[1] This can become even more confusing: If we do not specify a key for a style in a resource dictionary, then the target type is automatically used. I don’t recommend using this trick, and it makes the markup much harder to read.

[2] ComponentResourceKey isn’t necessarily required here, but it provides a convenient way to create a globally unique value. The combination of type plus string provides a unique namespace (strong, named CLR type) and a domain of names (the string). The only requirement is that the key is unique and implements GetHashCode and Equals correctly.

[3] There are several third-party solutions for adding themes to Windows—most notably “ThemeXP.” These options work by modifying core parts of Windows and they compromise the security of the system, so I strongly recommend not using them. Personally, I wish that Microsoft would make the theming model open and allowed third-party extensibility, but until that happens, I think it’s best to live with the built-in themes.

[4] The ?? operator is a C# 2.0 feature that works on Nullable<T>. In this case, if _check1.IsChecked returns null, then false will be used for the value of this expression.

[5] Notice the use of StaticResource in the code that follows. Because the Style object itself doesn’t use the dependency property system, we can’t use binding, styling, or dynamic resources to set properties of the style object. By using StaticResource, we can apply a resource exactly once—which has the negative effect that the style’s BasedOn property will not be updated if we modify ResourceDictionary.

Appendix

[1] Accelerator tables in User32 would translate from key strokes into WM_COMMAND messages.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset