Notes on WPF Changes
from November 2005 CTP
to February 2006 CTP
The February 2006 Community Technology Preview (CTP) build
of WinFX contains API changes from the November 2005 CTP. While the basic
design and principles discussed in Programming Windows Presentation
Foundation: Beta Edition are unchanged, some of the details are different
from our
last list of changes (from September 2005 CTP to November 2005 CTP).
You’ll also want to check out Karsten’s February
CTP of WinFX Published -- Breaking Changes.
General
- The XAML XML namespaces have changed. Instead of:
http://schemas.microsoft.com/winfx/avalon/2005
use:
http://schemas.microsoft.com/winfx/2006/xaml/presentation
and instead of:
http://schemas.microsoft.com/winfx/xaml/2005
use
http://schemas.microsoft.com/winfx/2006/xaml
- If a Grid has <RowDefinition> and <ColumnDefinition>
elements, these must now appear inside of <Grid.RowDefinitions> and
<Grid.ColumnDefinitions> elements. (While the Grid is part of
Layout, it appears here because Grid is used almost everywhere, so this
affects most things.) Previously, the use of these containing elements was
optional in most markup. The exception was use of <Grid> inside a
template – in the November CTP, using <Grid.Row/ColumnDefinitions>
wrappers around the row and column definitions didn’t work at all. Now, in
the February CTP, it has become mandatory to use these wrapping elements.
- Neither the UIAutomationProvider nor the UIAutomationTypes
assembly are needed for compilation of a WPF project.
Layout
- SinglePageViewer, the control for showing flow documents
one page at a time, is now called FlowDocumentPageViewer. There is also a
FlowDocumentScrollViewer which allows scrolled viewing instead of
paginated viewing.
- The TextFlow element has been removed. Flow documents are
now always represented using the FlowDocument element. If you put a
FlowDocument into your UI it will automatically be wrapped with a
FlowDocumentPageViewer. This provides pagination. If you want
non-paginated display of a flow document (which is what TextFlow used to
offer) you must explicitly wrap the TextFlow in a
FlowDocumentScrollViewer. By default that will provide scrollbars, but you
can disable scrolling just as you can with a normal ScrollViewer.
Graphics
- The tiling behaviour of all TileBrushes has change subtly.
This causes the brush examples that use tiling not to work correctly.
There is no workaround for these examples because they were in fact
relying on a bug in the old implementation. Previously, if you scaled a
brush in a way that preserved the aspect ratio, the proportion of the
brush covered by the Viewport would also be scaled. So if the brush was
stretched so the source only filled half the width of the brush, the
ViewPort range 0,0,1,1 would also only cover half the brush. So turning on
tiling would cause the image to repeat immediately. This was not the
intention. A ViewPort of range 0,0,1,1 is always meant to fill the entire
brush regardless of scaling. If tiling is required, a smaller ViewPort
must now be specified.
Writing Custom Controls
- To provide a default set of visuals for a custom control,
two steps are now required. First, set the DefaultStyleKeyProperty:
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl18),
new FrameworkPropertyMetadata(typeof(MyCustomControl18)));
Second, you must
supply a ThemeInfo assembly-level attribute:
[assembly:ThemeInfo(ResourceDictionaryLocation.SourceAssembly,
ResourceDictionaryLocation.SourceAssembly)]
ThemeInfo is
defined in the System.Windows namespace.
- For simple custom controls where you simply wish to reuse
some markup in a number of places, a UserControl type is now available.
This works much like the user controls in Windows Forms and ASP.NET: it
lets you design a custom control using all the same set of tools you’d use
to design a full UI. (It uses XAML as the basis for its appearance, just
like any full UI.)
- The use of placeholder attached properties shown in the
book is no longer a recommended way of indicating where the parts of a
template are. (Although it does still work.) The built-in control
templates now prefer the use of named parts – a control will look for
elements with a particular name in the template.
XAML
- The <?Mapping … ?> processing instructions used to
introduce mappings between .NET namespaces and XML namespaces has been
removed. In its place is a new URI syntax to be used for XML namespaces.
This new syntax encodes the .NET namespace and assembly information into
the XML namespace, removing the need for the processing instruction.
For example, if you had a DLL
called FooLib.dll that defined types in a namespace MyComponent.Stuff, whereas
previously you might have written
<?Mapping
ClrNamespace="MyComponent.Stuff" Assembly="FooLib"
XmlNamespace="foo"?>
<Window xmlns:foo="foo" ...>
...
You would now
just write:
<Window xmlns:foo="clr-namespace:MyComponent.Stuff;assembly=FooLib" ...>
...
Note that the “;assembly=AsmName”
part is optional. If you wish to refer to types defined in the same component
as the relevant XAML file, this would be sufficient:
<Window xmlns:foo="clr-namespace:MyComponent.Stuff
" ...>
...
- The System.Windows.Serialization namespace has been
renamed to System.Windows.Markup.
- The IAddChild interface no longer exists. Instead, when
child content is encountered, the XAML compiler will look for a property
annotated with the ContentPropertyAttribute custom attribute. If it finds
such a property, it will add child content to this property.
- If you want to drop raw XML into a XAML file, you
need to wrap it in the x:XData element, e.g.
<XmlDataProvider x:Key="Family" XPath="/Family/Person">
<Family xmlns="">
<Person Name="Tom" Age="9" />
<Person Name="John" Age="11" />
<Person Name="Melissa" Age="36" />
</Family>
</XmlDataProvider>
becomes:
<XmlDataProvider x:Key="Family" XPath="/Family/Person">
<x:XData>
<Family xmlns="">
<Person Name="Tom" Age="9" />
<Person Name="John" Age="11" />
<Person Name="Melissa" Age="36" />
</Family>
</x:XData>
</XmlDataProvider>
Interop
- There’s no need to add an XML prefix to bring in the
WindowsFormsIntegration assembly, e.g. the following:
<wfi:WindowsFormsHost>
...
</wfi:WindowsFormsHost>
becomes:
<WindowsFormsHost>
...
</WindowsFormsHost>
- Be careful where you get the WindowsFormsIntegration
assembly, make sure you pull in the right one. The wrong one on my
machine is:
c:\Program
Files\Reference Assemblies\Microsoft\WPF\v3.0\WindowsFormsIntegration.dll
the right one on my machine is:
C:\Program
Files\Microsoft Visual Studio
8\Common7\IDE\Cider\WindowsFormsIntegration.dll