Pro WPF in C# 2010 Windows Presentation Foundation with .NET 4.0 by  Matthew MacDonald

Contained herein is a collection of errata and comments on the MacDonald book. These comments are mine alone and are not endorsed or reviewed by APress or the books author.


Page Position on page comment or correction
xxxii first pph after What You Need to Use This Book the sentence reads "In order to create a WPF 4.0 need Visual Studio 2010..."
No, you can create .Net applications with notepad and the .Net release install (this includes the C# and VB compilers).  Visual Studio is a fine tool, but it is not a required tool to build .Net apps.
xxxii second pph after What You Need to Use This Book This pph talks about Expression Blend (the current version is 3). This pph implies that Blend is a tool purely for designers...but I'll recommend that as a developer you should learn the basics of this tool. For instance, Blend can be used to emit standard control 'Control Templates' that are useful for extending your WPF knowledge and provides a set of behaviors like mouse drag support.

Chapter 1 - Introduction WPF

Page Position on page comment or correction
2 first pph after first Note Reads "One component that's still in the User32".
Top level windows are HWND based windows, as are MessageBox instances and the two built-in dialogs (OpenFileDialog and SaveFileDialog; use Spy++ and see that the MessageBox, OpenFileDialog, and SaveFileDialog HWND class is #32770). In fact, the content of the MessageBox, OpenFileDialog, and SaveFileDialog windows are not WPF elements...they are classic Win32 GDI HWND's.
3 last pph reads: "WPF is intelligent enough to use hardware optimizations where possible, but it has a software fallback for everything".
WPF can perform software emulation if the video driver/hardware is lacking, but keep in mind that some of these operations are VERY slow. You can see how this works by setting up a machine and use the standard VGA driver and run a WPF app that performs some sort of animations.
4 WPF Tiers "WPF Tiers"...see my simple sample from module 01: WPFhardwareTiers  (Note: this app will display the Tier level (0, 1, or 2) and display pixel shader support levels in hardware and software)
7 first pph, 2 sentence reads: "However, Silverlight is designed to take a subset of the WPF platform..."
Silverlight is similar to WPF, but I would not call it a subset
13 last sentence reads: "There is no fallback to GDI+ or User32"
Except for common dialogs: MessageBox, OpenFileDialog, and SaveFileDialog (see note on page 2 above)
14 Note at bottom of page The System.Windows.Forms namespace is mostly reserved for WinForms; WPF includes an assembly named WindowsFormsIntegration and includes the System.Windows.Forms.Integration namespace that is used for hosting WinForm controls within WPF
17 WPF 4 bullet for WPF 3.5 SP1 states the it included DataGrid control (it does not...this control was available in codeplex prior to .Net 4 and now is included in .Net 4 WPF)
17 New Features last bullet on page reads "...and modify images with the WriteableBitmap class". This is not a new feature of .Net 4. This has been available since WPF was introduced
19 Multitargeting note that .Net 3.5 SP1 makes changes to primary .Net 2.0 types (for instance WaitHandle gets a new single parameter method overloads for WaitOne). This means that if you limit your project to .Net 2.0 and compile/test with .Net 3.5 SP1 applied might not run on a system with .Net 2.0 only installed). Also note that Visual Studio 2008 SP1 installs the .Net 3.5 SP1.
What is my point? To be sure to test on an OS with the minimum .Net runtime installed
20 top of page, 2nd pph reads: "...includes reference assemblies for each version of .NET"
As far as I can tell, the 'empty body' assemblies are only provided for .Net 3.5 and 4.0 (and not for 1.0, 1.1, 2.0 or 3.0)
20 .Net Client Profile, 2nd pph reads: "It does not include server-side features such as ASP.NET, debuggers, developer tools, code compilers, and legacy features..."
It does install the C# and Visual Basic compilers: csc.exe and vbc.exe, along with ngen.exe and installutil.exe. It does not provide ilasm.exe

Chapter 2 - XAML

Page Position on page comment or correction
23 second pph Reads "It's unlikely that you'll write XAML by hand".
I could not disagree more. The Visual Studio XAML designer is fine for quick demos and casual users. Writing directly to markup is a necessity for production quality professional code development. Yes, on occasion I do like the designer showing the rendered XAML (it allows me to select elements in the designer...and have the XAML highlighted so I can edit it)
25 The Variants of XAML, 3rd bullet reads "Silverlight XAML is a subset of WPF XAML". This is quite untrue. Silverlight and WPF are similar, but calling Silverlight a subset is misleading.
26 3rd  pph Reads "However, it is possible to use XAML without compiling it first"
This very much depends on what is in the XAML. For instance, specifying the x:Class attribute will require compiling. Also if you specify event handler hookups in XAML will also require compiling. Question: what compiler is used for XAML? Ask me for the answer
26 Creating XAML with Visual Studio, 2n pph Reads "...a whole host of tasks that are only possible - "
There exist a whole host of tasks only possible in code, but not in WPF XAML. It is certainly true that a number of tasks are much easier in XAML than in code. (disclaimer: in Silverlight there are tasks that can only be accomplished in XAML, but this is not the case in WPF). All examples that the author gives to support his thesis can be done in code as well.
Matter of fact, the authors' example of creating event handlers is an issue, since some WPF profressionals suggest that XAML is probably not a good place to reference them (code behind is suggested as a better location for hooking them up). Why? For the following reasons:
1) XAML is intended to be a common file between development and design. Designers should not need to see or interact with event handlers
2) XAML event handlers can only be hooked up to the code behind for the XAML file. You cannot hook the handler to another file or class.
3) there exists no XAML syntax to unhook an event handler
26 last pph Reads "Currently, Visual Studio has no design-time support for crafting animations."
True, but Expression Blend has this support. And you can open your solutions in Blend as well as Visual Studio. In fact, you can have the same solution open simultaneously in Blend and Visual Studio (as long as you are careful to save edits as you switch between the two editing environments)
28 bullet items top of page shows "Window, Page, and Application" but you can also specify NavigationWindow here as well. NavigationWindow is a kind-of Window and is used in developing a navigation application. But typically you do not need to explictly specify NavigationWindow (as will be shown in class).
28 section XAML namespaces  the snippet of XAML code shows xmlns:x="http://...."
Technically, the xml prefix can be anything, but by convention the xaml namespace prefix is 'x'. If you are searching in the MSDN documentation for the definition of one of the xaml namespace attributes (say, x:Class, x:Type, x:Name, x:Uuid, or x:Null) then you search using the 'x' prefix.
If searching on older MSDN documentation (prior to Visual Studio 2010), then be sure to disable search filtering (for some odd reason, if you have the older MSDN help viewer filtering on .Net you will not find these entries!!). See item below for page 47.
29 2nd bullet item on page We will be using the 'x' prefix throughout the class for the following items:
x:Name - to name an element (usually for accessing via code behind)
x:Type - the XAML equivalent to C# typeof() operator
x:Key - to specify a dictionary key value (used for key-value hash tables and dictionaries)
x:Static - to specify a static member of a class or enum
x:Class - to supply a namespace/class name for a derived node type
32 3rd pph This pph discusses Name and x:Name usage in XAML.
I always use x:Name, even if the element supports Name. Why? Because x:Name always works...Name does not always work.
34 XAML code snippet The author tends to be a bit verbose in writing his XAML. In this code snippet, you can remove the VerticalAlignment and HorizontalAlignment attributes and wind up with the same behavior.
All FrameworkElement (base class of Control, hence the base class of TextBox) define a default VerticalAlignment and HorizontalAlignment of Stretch
36 XAML code snippet writing the LinearGradientBrush.GradientStops nodes is optional. You can remove these and the code will still work.
41 middle of page Reads "The Grid displays all the controls it holds in an invisible layout of rows and columns..."
You can make this visible by setting the Grid attribute ShowGridLines = "true"
47 Tip this tip talks about commonly used namespace prefixes. You should also note that the 'x' prefix used for the XAML namespace is used in the documentation as well (see item above for page 26)
52 code snippet the author uses the LogicalTreeHelper class in this bit of code.  I'd like to point out that there is another helper class called the VisualTreeHelper. Here is a sample WPF application that will show the different output of these two helper classes. The application will use itself as the source of the visual or logical UI tree (refer to meeting 01 samples): DumpVisualAndLogicalTrees
The logical tree is going to display the classes that you will (mostly) see when setting up a UI object heirarchy (the classes you use in XAML).
The visual tree is going to display the logical tree plus a bunch more...these 'extra' classes are introduced by the control/window/element templates. We discuss templates later in the course.

Chapter 3 - Layout

Page Position on page comment or correction
65 pph middle of page this pph talks about some of the specialized objets derived from the abstract Panel class. The author lists InkCanvas as one of these. Problem is, InkCanvas is not derived from Panel or Canvas.
The only relationship InkCanvas has to Canvas is the class name happens to include the string: 'Canvas'.
67-68 Table 3-3: Layout Properties Note that this table shows the basic layout properties of panel children elements. All of these properties are defined on the base class: FrameworkElement (hence all controls have these properties)
68 note at top of page the note implies that attached properties (Grid.Row, Grid.Column, Canvas.Top, Canvas.Left, etc) are purely an container-child mechanism. As you will see later this, in general, is not the case.
For panels, the specific panel defined attached properties work only with contained children.
68 last sentence before Alignment section heading reads: "...don't give you the ablitity to explicitly position elements".
You can explicity postion elements within the Grid panel by using a combination of the following FrameworkElement properties of the children: Margin, VerticalAlignment and HorizontalAlignment
69 1st pph reads " Left for label and Stretch for a Button."
This is incorrect. The default HorizontalAlignment is the same for Label and Button: Stretch.
I think the author is confusing the HorizontalContentAlignment where is is Left for Label (the content positions to the left and top for Label controls and center for Button controls)
69 note at bottom of page author says that StackPanel has a VerticalAlignment and HorizontalAlignment property...but this is a behavior of all Panel types (due to the fact that VerticalAlignment and HorizontalAlignment come from the base class of Panel: FrameworkElement).
So, the behavior the author speaks of in this note is for all panel types, not just StackPanel
70 Margin section, first few sentences on page author says that you can, in XAML, specify a Margin using a single value (for all four sides) and 4 values for (left, top, right, bottom).
You can also specify 2 values like so:
<Button Margin="10,20" Content="Press Me" />
The two value syntax means the 1st value is for left and right, the 2nd value is for top and bottom. So for this example: left and right are 10, top and bottom are 20
74 note on automatically sized windows last pph in note reads at top of page: "To enable automatic window sizing, remove the Height and Width properties....and set the Window.SizeToContent property..."
You do not have to remove Height and Width. When you set the SizeToContent property, the Height and/or Width will be ignored depending  the SizeToContent setting.
85 Layout Rounding This section discusses the UseLayoutRounding attribute. Note that this attribute is available only in .Net 4.0
87-90 GridSplitter control info Note that the GridSplitter is a bit buggy. It has always been buggy and, unfortuneatly, is still be buggy in .Net 4.0.
See this link for more info on this problem: WPF GridSplitter randomly jumps when resizing | Microsoft Connect
95 Tip near center of page An interesting (and sometimes useful) feature of Canvas is this: you can absolutely position elements Canvas children (even at negative coordinates)  and then set the Canvas Width and Height to zero.
The result is a Canvas that disappears, but the 'child' controls remain at their relative offset positions from the upper left corner of the Canvas.
95-96 Z-Order section The author states that Canvas.ZIndex attached property can be used to affect Z order.
Not true for WPF. The attached property in WPF is Panel.ZIndex not Canvas.ZIndex (the author is correct for Silverlight, by the way)
All references to Canvas.ZIndex or Canvas.SetZIndex or Canvas.GetZIndex should be changes to Panel.ZIndex and Panel.SetZIndex and Panel.GetZIndex

Chapter 4 - Dependency Properties

Page Position on page comment or correction
106 second pph, first sentence Reads: "Dependency properties are a WPF-specific creation"
Dependency properties are used in WPF, Silverlight, and Windows Workflow Foundation. So I would not call this a WPF-specific creation.
Note that WPF, Silverlight, and WWF each have their own implementation of dependency properties, but they are very similar in design and intent.
107 2nd pph, first sentence Reads: "Instead, a  DependencyObject instance can be created only ...."
should read DependencyProperty and not DependencyObject. But this is not the whole reason...DependencyProperty is also a sealed class.
107 pph after first code snippet Reads "There are two steps involved in registering a dependency property. First, you create a FrameworkPropertyMetadata object..."
Note: there are 3 related classes for metadata: PropertyMetadata (the base class), UIPropertyMetadata, and FrameworkPropertyMetadata. Each class in this hierarchy adds more functionality. Use the one that makes sence for your property. In fact, there is no requirement to add metadata if none is required.
Also, the 4th bullet item in the text reads: "Optionally, a FrameworkPropertyMetadata object..." should really be "Optionally, a PropertyMetadata or dervided class instance..."
108 table item name: Inherits
This property is only valid for attached properties (DependencyProperty.RegisterAttached).
110-111 How WPF Uses Dependency Properites This sections discusses the order of precedence for Dependency Property value setting (see page 111, number list middle of page). Note that this precedence list is not nearly complete. Refer to the online documentation for a more complete precedence list: (title of article is: 'Dependency Property Value Precedence' in case this link breaks)
114 Property Change order of events (bullet items and numbered list) The Validate callback will be called first, followed by the Coerce callback. If the Coerce callback changes the value (including returning UnsetValue), then the Validate callback will be invoked again.
Only if the target property actually changes will the Changed callback get invoked. See my Meeting03 sample: DependencyPropertyCallbacksDemo

Chapter 5 - Routed Events

Page Position on page comment or correction
120  last pph, last sentence Reads: "...,both of which are defined in the base FrameworkElement class..."
No, the UIElement class defines AddHandler and RemoveHandler and RaiseEvent (even in Silverlight)
125 Note top of page reads: "In this situation, the top-level container isn't a window but an instance of the Page class"
Ok, the XAML files in your project might support this claim, but in fact the top-level visual element is a Window instance or a instance of a class dervied from Window. For Page, this top level visual element is NavigationWindow. So, if you specify a page.xaml file as your StartupUri (in App.xaml), then the system will automatically create a NavigationWindow for you so that the named page.xaml can be hosted within.
130 XAML snippet at top of page Reads: "<StackPanel Button.Click="..."
If you tried to type this out in XAML using Visual Studio XAML designer, you will find that the Intellisense will put ButtonBase.Click instead of Button.Click.
Either form will work (Intellisense knows that the Click event is actually defined on the abstract base class of Button: ButtonBase)...subject to the constraints listed in the note on top of the following page: 160
130 Note at top of page Setting up an attached event handerl to ButtonBase.Click or Buttton.Click or ToggleButton.Click will all do the same thing: Catch all Click events regardless of source.
(the author says otherwise, but testing confirms what I say above)
130-131 snippet near bottom of page using Tag property Note that Tag (of type Object) is for programmer use (it is not used by the system). It is defined on the FrameworkElement base class, so is available for all Control types.
145-157 MultiTouch Note that this is supported only for Windows 7 , also requires .Net 4.0
150 table on MultiTouch routed events You can see these new routed events listed in my DumpRoutedEvents demo from meeting 3 if you do the following:
1) load the project in Visual Studio 2010
2) change the project properties to build .Net 4 or .Net 4 Client Profile
3) rebuild and run (you dont need to be running on Windows 7 to see the new Routed Evetns listed)

Chapter 6 - Controls

Page Position on page comment or correction
165 2nd pph of Font Inheritence section, 2nd to last sentence Reads: "You can't set the FontSize property for the StackPanel..."
Actually, you can specify the setting on this and any FrameworkElement derived class. Any class that does not expose a FontXXX related property and derives from FrameworkElement, then you can use an attached properties exposed by the TextElement class: TextElement.FontSize="20"
173 pph near bottom of page starts with "In Chapter 3", 2nd sentence Reads: "Content controls use a compliemenatry property named Padding..."
All objects derived from the Control base class include Padding
190 sentence top of page Reads: "... the HorizontalScrollBarVisibility property is Hidden by default..."
No, it is Disabled by default. If it were Hidden, then  you could use Home or End to scroll...but you can't

Chapter 7 - The Application

Page Position on page comment or correction
219 table on ShutdownMode enum values These modes are for top-level independent windows that are not setup with ownership (Window.Owner property)
220 table on application events the Startup event is said can be used to check command-line arguments. Sure, but you can obtain the command line arguments anytime later in the application lifetime simply by using the Environment.GetCommandLineArgs method
223 Handling Command-line Arguments see my note for page 220 above
232 side note on UAC some important additional information on manifest files and inclusion of the requestedPrivileges element
1) starting with Vista and later OS's, embedded manifests take precedence over external manifests (this is opposite to what XP/server 2003 does)
2) adding any form of the requestedPrivileges element will disable virtualization (a file system/registry feature added to Vista and later OS's). This is why one would add the asInvoker element since it is the default, but adding the element will disable virtualization. Another way to think about the requestedPrivileges element is this: when you add it to a manifest you are claiming that the application is Vista/Win7 knowledgeable.
242 last numeric item in first numbered collection top of page author states that an IOException is thrown if a satellite assembly is not found. I very much doubt this.
Satellite assemblies are optional. So on a multi-language OS where the user has changed the UI culture, then the .Net loader will attempt to probe to locate satellite assemblies. If a specific satellite is not found then it should default to the 'default' culture.
243 Preparing Markup Elements for Localization section note: the x:Uid attribute is the one exception to the rule: "XAML element-attribute nodes cannot specify attributes"
For example, take the following XAML fragment:
      ...stuff goes here
I had said that nodes where a '.' appears (such as <Button.Content>) cannot specify attributes. This is true except for the x:Uid attribute.

Chapter 8 - Element Binding

Page Position on page comment or correction
261 code snippet showing XAML Binding when setting a Binding Source to refer to a ResourceDictionary keyed value, you must use StaticResource and not DynamicResource like so:
Text="{Binding Source={StaticResource someResKey}..."
507 side bar on Designing Data Access Components, last sentence of first bullet item Reads: "One way to ensure the connection is closed at the appropriate time is with a using block"
First time I read this, I did not know what a 'using block' was...the author is referring to the using keyword and having the end of the using scope call Dispose for you automatically.
515 Note top of page you can also get a BindingExpression via the static BindingOperations class
515 last code snippet on page, showing call to OnPropertyChanged you should verify that the property is actually changing prior to calling PropertyChanged event. Also remember to call PropertyChanged event only after the property is changed (very important). The code should be rewritten like so:
set {
  if (unitCost != value)
    unitCost = value;
    OnPropertyChanged(new PropertyChangedEventArgs("UnitCost"));
516 table 16-4 DisplayMemberPath and ItemTemplate are mutually exclusive properties, only one can be specified
518 2 bullet item bottom of page An important point is missed in discussing ToString().
The use of ToString() acts like a onetime changes on the source will ever propagate to the target (even if you implement INotifyPropertyChanged)
521 first pph after Note, middle of page Reads: "You can derive a custom collection from ObservableCollection to customize the way it works, but that's not necessary"
I've seen implementations that do the following class inheritence (with absolutly no specialization or extensions):
public class PersonCollection : ObservableCollection<Person>
so that the PersonCollection can be referenced within XAML. XAML has issues with generic syntax.
535 two bullets, top of page I'd like to make this point very clear: a MultiBinding requires you to reference a Converter. You cannot create a MultiBinding element without the Converter attribute.

Chapter 9 - Commands

Page Position on page comment or correction
269 1st pph under the ending of the note Reads: "...implements the ICommand interface privatly and then adds..."
No, the ICommand interface is implemented explicity, not privately. You can still access the ICommand methods, you just need to explicity cast to ICommand to call them.
269 note at bottom of page another reason to not use the RoutedUICommand text: it does not support mnemonics (refer to p. 175 for mnemonics)
270 list of ApplicationCommands near bottom of page missing: NotACommand
This is useful for switching off a controls built-in InputBinding for a given command.
272 top of page code snippets show how you can use either
Command = "ApplicationCommands.New"  
Command = "New"
This short cut only works for the built-in commands (ApplicationCommands, NavigationCommands, EditingCommands, ComponentCommands, and MediaCommands). If you create your own custom commands, then you must fully qualify the names when you assign them to the Command parameter.

NOTE: you might find the following syntax in source code:
Command = "{x:Static ApplicaitonCommands.New}"
this will work, but takes more it turns out, there exists a TypeConverter for string to RoutedUICommand that allows the shorter syntax:
Command="ApplicationCommands.New" or Command="New"
and this same converter can be used for your custom commands (you just need the full type name)

Chapter 10 - Resources

Page Position on page comment or correction
303 Note bottom of page Reads: "However, it's not acceptable to merge resource dictionaries that use the same resource names."
This is untrue (as demonstrated in my class). See: Merged Resource Dictionaries

Chapter 11 - Styles and Behavior

Page Position on page comment or correction

Chapter 12 - Shapes, Brushes, and Transforms

Page Position on page comment or correction
337 Note, center of page Reads: "If you fail to set the Stroke or Fill property, your shape won't appear at all"
The default Fill and Stroke are initially set to null brushes. So not only will you not see the shape, but it can't be used for hit testing (as a transparent element)
340 first pph after tip, about the fifth sentence Reads: "The Grid is a bit more flexible because it allows you to place as many elements as you want in the same cell (although it doesn't let you postion squres and ellipsis in different parts of that cell)"
Sure you can position shapes within a cell. Use a Margin to postion multiple elements within a single cell (to do this with some elements may require the use of explicit Width/Height and/or VerticalAlignment/HorizontalAlignment)
The point the author is attempting to make here is this: Canvas is the preferred container for vector graphics due to absolute postioning. Also remember that the Canvas Width and Height is not required to be non-zero to view Canvas children.
343 4th pph down Reads: "However, consider what happens if you remove the Width and Height properties from the Canvas."
The description is a bit misleading I think. Remember that the Canvas can have zero Width and Height and the Canvas children will still display. But when you try to do this when the Canvas is a child of a Viewbox, you will see that the children, in fact, disappear.
This is happening because as the Canvas Width/Height tend to zero, this acts like a Zoom-in as the Viewbox attempts to scale up the child. The Canvas children disappear because the during the zoom-in, they move right off the lower right corner of the Viewbox. See my sample: Ch12p343_ResizeWithViewbox
343 Line section bottom of page this section discusses the Line shape and how it is positioned. I find Line a bit 'quirky' due mostly to it being derived from the Shape class. Line has a Width and Height (along with AcutalWidth, AcutalHeight), but these don't usually get used. To display a line you need to specify at the very minimum X2 and/or Y2 and Stroke.
The line origin (X1,Y1) is an offset from the upper left corner of the Line shape Width/Height.
Create a demo WPF app using the Visual Studio project template. Create a single element in the supplied Grid like so:
<Line X1="100" Y1="100" X2="200" Y2="200" Stroke="Black" />
now add the following attributes for VerticalAlignment and HorizontalAlignment:
<Line X1="100" Y1="100" X2="200" Y2="200" Stroke="Black" VerticalAlignment="Center" HorizontalAlignment="Center" />
So, did the line center? No?? Well, what did center is the 'bounding rectangle' based on the Line origin of X1=0 Y1=0 and the supplied X2,Y2 in you XAML.
343-344 last pph Reads: "However, it's perfectly reasonable to use negative coordinates for a line...."
You can use negative coordinates for a line, and use negative position information for any shape when positioning within a container (say, Canvas).

But I'd strike out most of what this pph says (about Margin, flow control, Vertical and Horiz alignment). Shape elements are a kind-of FrameworkElement...they all honor flow layout.
(for instance, check out what Expression Blend puts in your XAML file when you add Rectangles, Ellipse, or Line...but you will not see Line since Blend uses Path for everything except simple Rectangle and Ellipse)
366 last sentence before the Note Reads: "When you perform a series of transformations with the TransformGroup, WPF fuses your transforms together into a single MatrixTransform..."

You might have noticed by now that you cannot do simple arithmatic within XAML (addition, subtraction, multiplication). Well, actually you can if you really wish to. These transforms provide a means to express additons and multipications in XAML where you can extract result by accessing the MatrixTransform.Matrix properties: M11, M12, M21, M22 and OffsetX and OffsetY
368 pph after figure 12-24, middle sentence Reads: "Fortunately, WPF has a solution with the handy RenderTransformOrigin property, which is supported by all shapes"
Yes, this is true, but the description is very limiting. The RenderTransformOrigin property is defined in the UIElement class (the base class of FrameworkElement). Hence, it is available for almost every type you will be using in WPF: Controls, Panels, Shapes, etc

Chapter 13 - Geometries and Drawings

Page Position on page comment or correction
382 note on page This discription of why Geomerty.Transform is different or perferred over FrameworkElement.LayoutTransform or UIElement.RenderTransform is a bit lacking, I think.
It would help to see a live example. So I changed my ShapeVsPath sample to add a ReadMe.txt file that will guide you through adding a ScaleTransform to a Path and then a Geometry so you can see the difference in behavior. To find the ShapeVsPath demo, check my class page under meeting 5
Note that this sample also runs into an issue with a Freezable type that is actually frozen (we will be discussing Freezable in another meeting)
387 first sentence under section Bezier Curves  Reads: "Bezier curves ... incorporates two control points..."
Cubic Bezier curves have two control points. Quadratic Bezier has one one. WPF supports both types of Bezier curves (but design tools like Expression Blend only produce Cubic Bezier)
393-394 table 13-6 and 13-7 I am not one that should be ridiculing anyone's naming conventions, but I do need to point this out...
You might notice that there is a class called ImageDrawing and one called DrawingImage.
  1)  ImageDrawing is a Drawing that wraps a image (could be a bitmap). This cannot be rendered by itself.
  2) DrawingImage is ImageSource and allows you to host a Drawing inside of an Image element. This is used for rendering
402 first bullet, bottom of page Failure to call the AddVisualChild/AddLogicalChild methods will also break event / command routing
404 Tip Reads: "By setting the background to white (rather than transparent),.."
I think should be: "By setting the background to a non-null brush,..."
(where a SolidColorBrush with Colors.Transparent would be just as good a Colors.White wrt hit testing.)

Chapter 14 - Effects and Visuals

Page Position on page comment or correction
412 pph top of page As of .Net 3.5 SP1, BitmapEffect is deprecated. Instead, you should be using Effects
Some addtional info: BitmapEffect is mostly software only supported (as far as I know). But BitmapEffects can be printed, Effects cannot.

Chapter 15 - Animation Basics

Page Position on page comment or correction

Chapter 16 - Advanced Animation

Page Position on page comment or correction

Chapter 17 - Control Templates

Page Position on page comment or correction
506 2nd pph after Understanding Templates section, last sentence Reads: "That recipe is called a control template, and it's defined using a block of XAML markup"
Note that control templates can be written in code as well. XAML is not required to write a control template.
507 XAML snippet the snippet shows an element-attribute synatx for Boolean value settings. You could write your XAML this way if you wish, but it is usually written this way:
<Trigger Property="IsKeyboardFocused"
       <Setter TargetName="Chrome"
<Trigger Property="ToggleButton.IsChecked"
        <Setter TargetName="Chrome"
<Trigger Property="IsEnabled"
         <Setter Property="Foreground"
510 2nd pph after Dissecting Controls section header, 1st sentence Reads: "The WPF documentation doesn't list the XAML for standard control templates."
True enough, but the XAML is available in two places:
a) Platform SDK WPF samples as all of the theme XAML files for standard controls
b) Expression Studio 3 has copies of the theme XAML files for standard controls
510 in same pph as listed above The author suggest that you can programmatically access a controls Template property and then use the XamlWriter class to dump it out.
If you do this, you will be missing a bulk of default styles including Brush definitions. The better approch is the one that I take in my DumpStandardControlStyle demo in meeting 5:
1) search for the standard control Style by using the following static resource search (example of looking for Button style):
    Style style = FindResource(typeof(Button)) as Style;
2) then dump the Style out using the XamlWriter class. You will find the ControlTemplate there along with a boat load of supporting Brushes, and default properties .
514 4th pph, last sentence (near center of page) Reads: "'s also a requirement, or the ContentPresenter won't work."
This is discussing the usage of TargetType in ControlTemplate. TargetType is not required for ContentPresenter. Here is a snippet:

<ControlTemplate TargetType="{x:Type Button}">
      <ContentPresenter Content="{TemplateBinding Content}" />

This can be rewritten as this if you wish:

      <ContentPresenter Content="{TemplateBinding ContentControl.Content}" />

You see, all the TargetType does is enable a more terse template definition (assuming you will have a lot more uses of TemplateBinding).

What the author is getting at is the following (and mentioned a few pages later in a note on page 461): the ContentPresenter has an implicit TemplateBinding to the ContentControl.Content property and you do not need to declare an explicit TemplateBinding for it ... if and only if you have a TargetType specified to a ContentControl or class derived from ContentControl like so:

<ControlTemplate TargetType="{x:Type Button}">
      <ContentPresenter  />
516 2nd sentence, first pph Author says that TemplateBinding can specify a Freezable source property.
Freezable class is the base of: Trigger, Timeline (Animations), Brush, Drawing, BitmapEffect and Effect, Geometry, GradientStop, ImageSource (Bitmaps and DrawingImage), MediaPlayer, Pen, plus more...but these are the important ones.
528 first pph after last code snippet, last sentence The author describes a problem if a merged dictionary contains a key that may be defined within another merged dictionary.
But this is not a problem for either WPF or Sliverlight. I'm not sure what the author is worried about, but testing (and MSDN documentation) indicates that this is not an issue for merged dictionaries.
480 Note on page about TemplatePart I've got a few things to say about the reference to the class type:
Note that the class might be a base class, and the concrete class might be restricted. For instance, the TextBox (see base class TextBoxBase) has the following TemplatePartAttribute:
TemplatePart(Name="PART_ContentHost", Type=typeof(FrameworkElement))
but the type is actually restricted to ScrollViewer or Decorator or types derived from these two types.
(also note that the MSDN documentation is incorrect, it says ScrollViewer and AdornerDecorator but the code only restricts to ScrollViewer and Decorator)
As far as I know, the TemplatePartAttribute is purely a documentation element (there is no runtime or compile time enforcement or verifications)

Chapter 18 - Custom Elements

Page Position on page comment or correction

Chapter 19 - Data Binding

Page Position on page comment or correction
600 side bar on Designing Data Access Components, last sentence of first bullet item Reads: "One way to ensure the connection is closed at the appropriate time is with a using block"
First time I read this, I did not know what a 'using block' was...the author is referring to the using keyword and having the end of the using scope call Dispose for you automatically.
608 Note in lower part of page you can also get a BindingExpression via the static BindingOperations class
609 code snippet at top of page, showing  UnitCost property you should verify that the property is actually changing prior to calling PropertyChanged event. Also remember to call PropertyChanged event only after the property is changed (very important). The code should be rewritten like so:
set {
  if (unitCost != value)
    unitCost = value;
    OnPropertyChanged(new PropertyChangedEventArgs("UnitCost"));
610 table 19-1 DisplayMemberPath and ItemTemplate are mutually exclusive properties, only one can be specified
612 2 bullet item bottom of page An important point is missed in discussing ToString().
The use of ToString() acts like a onetime changes on the source will ever propagate to the target (even if you implement INotifyPropertyChanged)
614 first pph after Note, middle of page Reads: "You can derive a custom collection from ObservableCollection to customize the way it works, but that's not necessary"
I've seen implementations that do the following class inheritence (with absolutly no specialization or extensions):
public class PersonCollection : ObservableCollection<Person>
so that the PersonCollection can be referenced within XAML. XAML has issues with generic syntax.

Chapter 20 - Formatting Bound Data

Page Position on page comment or correction
675 first bullet item on page Reads: "Data triggers work like the property triggers you learned about with styles in Chapter 12, except they don't require dependency properties"
I think this needs a bit of explaining.
A property trigger was written like so:
<Trigger Property="Control.IsMouseOver" Value="True">...
where the Property attribute must reference a dependency property.
On the other hand, a data trigger is written like so (instead of a Property attribute, you have a Binding attribute):
<DataTrigger Binding="{Binding Path=IsMale}" Value="False">...
the use of a Binding means that that source of the binding is not required to be a dependency property
NOTE: but in either case (Trigger or DataTrigger), the contained collection of Setter objects are restricted to dependency property targets.

Chapter 21 - Data Views

Page Position on page comment or correction
691 last buttet item on page Reads "If you data source doesn't implement IBindingList or IList but it implements IEnumerable, you get a basic CollectionView"
Actually, the implemenation you get back is an internal class instance called MS.Internal.Data.EnumerableCollectionView. But since you can only access the base class, CollectionView, then basically this statement is correct.
Also, there is a missing criteria in this list: If your data source implements ICollectionView, then you get a ItemCollection

Chapter 22 - Lists, Grids, and Trees

Page Position on page comment or correction

Chapter 23 - Windows

Page Position on page comment or correction
752-753 table on Window properties AllowsTransparency can only be set True if and only if WindowStyle is set to none (ie, no frame)
SizeToContent can be set in XAML along with Width and Height. At design time Width and Height take precedence, at runtime SizeToContent takes precedence upon first load and rederning (the user or code can change Width and Height thereafter)
NOTE: currently (for .Net 2.0-3.5) there is no way to create a top level window that is Hidden. This capablity is to be available in .Net 4.0
755 1st full pph on page Reads: "Closing a window is equally easy, using the Close() method"
Ok, true, but modal windows probably should not be calling the Close method explicitly. Instead, modal windows would typically set the Window.DialogResult property to True or False. Why? Because this is the result handed back by the return of the ShowDialog() method. Setting this property will cause the modal to close while not setting the property and calling Close explicitly will send a 'false' back as a return value (in WinForms, the default return value would be 'Cancel' if Close was called).
Note that this is the same behavior that was part of WinForms modal Form. Big difference between WinForms and WPF: attempting to set the Window.DialogResult property on a modelss window will throw an exception in WPF.
You might wish to programmatically determin within your Window class implemenation if your window is running in modal or modelss mode. You can do this via the following code:
System.Windows.Interop.ComponentDispatcher.IsThreadModal property
NOTE: this property is not set during the Window construct or load. So, if you wish to know when the property is set, then handle the  System.Windows.Interop.ComponentDispatcher.EnterThreadModal event.
(Check out my note about page 225 below)
756 Discussion of the Settings tab

The author mentions the Settings tab and the Properties.Settings.Default static accessor for type safe access. Some things that the author does not say:
1) Application scope settings are read-only
2) User scope settings are read-write (see note below)
3) A number or data types shown are WinForm types and not WPF types (System.Drawing namespace types are all WinForms, not WPF. To use WPF types you need to browse for the System.Windows.Media namespace for the FontXXX types and Color. And use System.Windows namespace for Rect, Point, and Size)
4) Custom types can be added to this (but will probably require some WinForm programming if you need to add custom editors for your custom types)
5) You can reference settings from within XAML if you wish. See the following example that makes use of the Static markup extension:

The User scope settings are read and write. This means that, in code, you can call Properties.Settings.Default.Save() to save changes or Properties.Settings.Default.Restore() to remove the changes. Note that, by default, these 'changes' are saved in a different config file that will be created under the current user profile (Vista/Win7 under \Users\<username>\AppData/Local\<app name>\;XP under \Documents and Settings\<username>\Local Settings\Application Data\<this process name>\

Also note that the default settings provider will keep a copy of user settings changes based on the current application absolute path (if another copy of the application is in another folder, then the saved changes will not be shared between these applications). You can replace the default settings provider so you can gain control of this mechanism if you wish.

762 The Dialog Model section, 1st pph top of page Reads: "You can take advantage of another shortcut."
Ok, but here are some issues you need to consider
1) setting DialogResult = true or false will close the dialog
2) setting DialogResult = null will not close the dialog
3) setting DialogResult to true, false, or null will cause an exception if the dialog was not shown modal
4) setting a button with IsDefault = true will not cause the DialogResult to be set true (contrary to the authors comment in this pph), nor will the Dialog close.
5) setting a button with IsCancel=true will cause the dialog to close when the button is clicked (the default DialogResult will be false). Note that the Click event handler will be called if you click the cancel button or you press the Esc key (but not if you press the "X" close button on the caption bar).
6) you can set DialogResult only once during the modal display of the dialog

Actually, I find in interesting that the Window.ShowDialog returns a nullable bool instead of a standard bool. As far as I can tell, ShowDialog always returns either True or False and never returns null. The Window.DialogResult property is a nullable bool, but the only way that the DialogResult will be null is if and only if the Window is displayed in modeless mode (and you access the will be null)
(Check out my note about page 218 above)
763 last pph just before the Nonrectangular window section Reads: "You won't find any color pickers, font pickers, or folder browsers..."
You can use WinForm interop for ColorDialog and FolderBrowserDialog, but FontDialog is a bit tricky and probably not worth the effort to attempt to use via interop. Instead, you can use a WPF implemenation of FontDialog available via CodePlex: and a SDK sample: Font Dialog Box Demo

Chapter 24 - Pages and Navigation

Page Position on page comment or correction

Chapter 25 - Menus, Toolbars, and Ribbons

Page Position on page comment or correction
848 2nd to last pph prior to section The Overflow Menu Reads: "(In other words, there is a ToolBarItem class)."
Should read "(In other words, there is no ToolBarItem class)."
If you use Reflector, you might notice a ToolbarItem class (lower case 'b'), but this is an internal class used with UI Automation

Chapter 26 - Sound and Video

Page Position on page comment or correction

Chapter 27- 3-D Drawing

Page Position on page comment or correction

Chapter 28 - Documents

Page Position on page comment or correction

Chapter 29 - Printing

Page Position on page comment or correction

Chapter 30 - Interacting with Windows Forms

Page Position on page comment or correction

Chapter 31 - Multithreading

Page Position on page comment or correction

Chapter 32 - The Add-in Model

Page Position on page comment or correction

Chapter 33 - ClickOnce Deployment

Page Position on page comment or correction