May 2009 - Posts
In the Beta2 of .NET 4, we’re working on type forwarding several types from WindowsBase.dll to System.Xaml.dll. WindowsBase will have a dependency on System.Xaml. System.Xaml will no longer depend on WindowsBase.
On Friday we discovered some issues with Cider/Blend that we’ll have to work with those teams to resolve.
My guess is that these 2 tools have needed to differentiate between Silverlight and .NET’s ContentPropertyAttribute…and have probably moved to use the full name of the type.
Unfortunately, full name comparisons don’t respect TypeForwardedToAttributes.
Wouldn't it be nice if packaging/specs for all electronics goods had a standard way of listing their power use when on, standby, etc...
I'm looking to buy a new monitor for home, and found this list helpful: http://reviews.cnet.com/green-tech/monitor-comparison-chart/?tag=contentBody;nextPage
Anson, a WPF Program Manager, has great knowledge of the direction WPF to help touch enable your WPF applications. Watch the Channel 9 video "Multi-touch in WPF 4 Beta 1" and follow up with your questions/comments on that page.
Beta1 of WPF4 has some, but not all of the Multi-Touch features coming to you in WPF4.
HTML provides a simple way to do references from one property to another object easily.
<LABEL FOR="moreinfo">
send more information
<INPUT NAME="moreinfo" TYPE=CHECKBOX ID="moreinfo">
</LABEL>
From HTMLCodeTutorial.com
We wanted XAML Vocabularies to have the same simplicity (and some more capabilities), so that is why we have invested in Name References in XAML2009 and System.XAML.
Name references should work as backwards or forwards references.
Type Authors – Enable Reference by Name for appropriate Properties
Label.Target is a UIElement, however we’d like to enable a simple Name reference to other objects declared in XAML.
<Label Target="firstName" >_First name:</Label>
<TextBox Name="firstName" />
In order to enable users to do this, type authors should use System.Xaml’s NameReferenceConverter on your property.
[TypeConverter(typeof(NameReferenceConverter))]
public UIElement Target
{ … }
Luke put this example of what he’d like to do in a comment on my blog:
<Table Name="Customer"/>
<Table Name="Order"/>
<Relationship From="Customer" To="Order" Cardinality="OneToMany"/>
See “Code Sample using NameReferenceConverter” at the bottom of this post that implements Table, Relationship and demos them.
XAML Users – Use a reference to another object anywhere
XAML2009 introduces the a new built-in markup extension called {x:Reference}. Using it, you can explicitly set the value of the target property with a reference to the named object. You can also use it as an object element which can reside in a collection.
If From/To didn’t use NameReferenceConverter (as described above), the XAML author could do this:
<Table Name="Customer"/>
<Table Name="Order"/>
<Relationship From="{x:Reference Customer}" To="{x:Reference Order}" Cardinality="OneToMany"/>
Type Authors – Build more complex minilanguages with integrated Name support
Somebody may want to build an expression engine that could “dot down” to arbitrary properties of objects like this:
<Button Height="{Expression namedObject1.Height + namedObject2.Height / 2}"/>
A markup extension or type converter could call GetService(typeof(IXamlNameResolver)) in order to get access to a service to search for named objects already encountered, or register a request for an object that hasn’t been seen yet. A sample of this may be worthy of another post.
Creating documents with x:Reference
XamlServices.Save() will add x:Reference as appropriate, based on the object graph you pass it.
Summary
Named references in XAML2009 is an important feature, helping to enable a number of scenarios for different XAML Vocabularies. We hope you enjoy.
(Please see “Note – What works where” at the very bottom of this post.)
Code Sample using NameReferenceConverter
Requires Beta1 of .NET 4.
(Command Line project with WindowsBase.dll and System.Xaml.dll as additional assembly references).
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Windows.Markup;
5: using System.Xaml;
6:
7: namespace ReferenceExample
8: {
9:
10: //when run, this program creates the following output:
11: /*
12: <DatabaseCollection Capacity="4" xmlns="clr-namespace:ReferenceExample;assembly=ReferenceExample">
13: <Table Name="Customer" />
14: <Table Name="Order" />
15: <Relationship Cardinality="OneToMany" From="Customer" To="Order" />
16: <Relationship Cardinality="OneToOne" From="Customer" />
17: </DatabaseCollection>
18: */
19:
20: class Program
21: {
22: static void Main(string[] args)
23: {
24: Table t1 = new Table();
25: t1.Name = "Customer";
26: Table t2 = new Table();
27: t2.Name = "Order";
28: Relationship r1 = new Relationship();
29: r1.From = t1;
30: r1.To = t2;
31: r1.Cardinality = Cardinality.OneToMany;
32: Relationship r2 = new Relationship();
33: r2.From = t1;
34:
35: DatabaseCollection dc = new DatabaseCollection();
36: dc.Add(t1);
37: dc.Add(t2);
38: dc.Add(r1);
39: dc.Add(r2);
40:
41: string xamlString = XamlServices.Save(dc);
42: Console.WriteLine(xamlString);
43:
44: Console.WriteLine("--press any key--");
45: Console.ReadKey();
46: }
47: }
48:
49: public abstract class DatabaseObject {}
50:
51: public class DatabaseCollection : List<DatabaseObject> {}
52:
53: [RuntimeNameProperty("Name")]
54: public class Table : DatabaseObject
55: {
56: public string Name { get; set; }
57: }
58: public class Relationship : DatabaseObject
59: {
60: [TypeConverter(typeof(NameReferenceConverter2))]
61: [DefaultValue(null)]
62: public Table From { get; set; }
63:
64: [TypeConverter(typeof(NameReferenceConverter2))]
65: [DefaultValue(null)]
66: public Table To { get; set; }
67:
68: public Cardinality Cardinality { get; set; }
69: }
70:
71: public enum Cardinality
72: {
73: OneToOne,
74: OneToMany,
75: ManyToMany,
76: }
77:
78: //In .NET 4 Beta1, System.Xaml.NameReferenceConverter doesn't have ConvertTo/CanConvertTo implemented.
79: //Working around with a version hard coded for this scenario...
80: public class NameReferenceConverter2 : NameReferenceConverter
81: {
82: public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
83: {
84: return destinationType == typeof(string);
85: }
86: public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
87: {
88: Table table = value as Table;
89: return table.Name;
90: }
91: }
92:
93: }
[Note – what works where]
In .NET 4 Beta1, NameReferenceConverter + IXamlNameResolver should be mostly functional (we’ve fixed a few bugs since). {x:Reference} and <x:Reference /> won’t work when you compile XAML, but we plan to address this in .NET 4 (we believe that moving x:Reference from System.Xaml.Replacements to System.Windows.Markup will just make that work in the compiler). Cider/Blend will likely won’t work initially. See “Yes, XAML2009 isn't everywhere yet”
[This post was originally posted on November 29, 2004 and may still be available via this link. I’m reposting to ensure that it remains available. In 2008, I wrote an updated “8 Benefits of XAML for UI and Beyond”]
I like the description that Karsten, Tim, and Arik wrote about XAML from the What's New in the "Avalon" Community Technology Preview article:
XAML. "Avalon" also introduces XAML, a markup language to declaratively represent user interface for Windows applications, improving the richness of the tools with which developers and designers can compose and repurpose UI. For Web developers, XAML provides a familiar UI description paradigm. XAML also enables the separation of UI design from the underlying code, enabling developers and designers to work more closely together.
On top of that, I thought it would be interesting to share the 7 major goals we had in mind while designing XAML. Generally, many design decisions require balancing the different goals (as they often conflict).
Be XML
All valid XAML files must be valid XML files. The opposite isn't always true…all XML files are not XAML files. This is important because of the ecosystem of tools, systems, APIs and developers familiar with XML.
Describe Hierarchy of Objects in a Human Readable/Writable Way
Markup provides a concise way to represent a set of objects arranged in a hierarchy. It is more readable and writable than programming languages. It is the best format to represent the initial state of an object hierarchy.
Provide Page-Based Programming Model
Like DHTML + ASP.NET, XAML provides a way for you to associate programming code with the declarative markup. We recommend people having a code behind file (.xaml.vb or .xaml.cs for example.), but also support code being directly embedded inside of a XAML file. XAML and any .Net language can work together in this page-based programming model. The .Net Language needs to support CodeDOM and a set of language specific MSBuild target files. In this CTP, we support C# or Visual Basic. We will likely add J# support by spring and we look forward to supporting other languages from Microsoft (C++ and JScript) and other companies in the future.
Be Source Code or Runtime Instructions
Sometimes XAML is treated as source code, that gets compiled into an assembly (.exe or .dll) as a combination of a binary representation and IL. Other times, it is interesting to build XAML at a later time and interpret it at runtime. While we love the benefits that a markup representation give developers, we prefer to deal with XAML at compile time, not run time.
Take Advantage of Strong-Typing
Objects that have a strongly-typed OM (object model) are better systems to program with. DHTML is a system that was very string-based, and thus difficult to debug. Systems that leverage XAML (including Avalon), get the benefit of using strings in markup, but can get compile time errors for markup or code. XAML's default is that it must understand every tag and attribute. HTML defaults to ignoring any mistyped element name, attribute name or attribute value. While there is a place for this ignoring to allow for forward compatibility, we'll provide a different mechanism for this.
Be Toolable
Systems described in XAML will be creatable and consumable by a wide set of tools. We hope to have a clear & minimal set of rules on how classes get represented in markup. We hope to encourage an ecosystem of tools.
Be Useful for Much More than UI Definitions
While XAML will be heavily used in the vast majority of Avalon applications or documents, its uses will be many. I'm writing a command line tool right now that uses a vocabulary of classes in a XAML file used as data to drive the application. I'm getting the following benefits over just using XML to represent this data: 1) validation of my data file without having to write a schema and using a validating xml reader; 2) my code that needs to interact with this data, does it in a strongly typed way; Intellisense works in my code behind; 3) my system has built in extensibility, instead of being tied to specific tag names, I'm tied to a specific class (and subclassing allows others to provide other specializations of that class.) 4) etc… (When this tool is done, I plan on sharing it)
Don't Forget Why We Built XAML - Avalon!
That all being said, I believe it is important to remember that for as interesting as XAML itself may be to some, we are building a comprehensive platform with Avalon. Some people blog excitedly about XAML…however, many of them are actually discussing the power of Avalon, not XAML. XAML is a way to use declarative markup with a set of CLR classes. We're investing much more R&D in the Avalon API and Avalon infrastructure than we are in the parser and markup compiler.
Some Related Previous XAML Posts
Josh Twist has an interesting post arguing that XAML writability is very important, and that many people want to edit XAML directly.
While we have focused on ease of human authoring of XAML as a goal, it has always been balanced with other goals, like toolability. Some quotes:
His two examples of things that could improve WPF hand authoring of XAML:
- RowDefinitionCollection, ColumnDefinitionCollection could both have a type converter associated with them to support a syntax like that.
- Transform used to have a type converter to make ScaleTransform, RotateTransform easier that we removed late in 3.0…yes, a markup extension could also be used.
Yes, we have a bit of a love/hate relationship with minilanguages. We need to reevaluate the pros/cons of minilanguages (as Mike Hillberg was just mentioning the other day) with the XAML team, the WPF/Silverlight team, and XAML based tools teams.
In these cases, there are things that type authors can do (add a type converter), things that developers can do (build a type converter), and future things we could do in the XAML language.
I’m interested to see your opinions on the issues that Josh brings up in his post.
Jaime posted a good list of features in WPF4, including what is in Beta1 and what is coming later.
NickBaker77 is on the WPF Forum looking for a tool to find unused Resources in XAML files. I’m not sure if one exists…however, for those of you looking to try out System.Xaml.dll APIs, I replied with an outline on how I would write such a tool.
Forum Post
Channel9! Now that XAML2009 and System.XAML are in your hands, Mike Shim and I visited Adam Kinney to briefly discuss XAML in .NET 4 on Channel 9. We discuss some language features, show of the latest version of XamlT.Pad, and more.
Update:
The last time I was on Channel 9 was "Rob Relyea - There's something about XAML" in July 2006, 4 months before .NET 3 shipped.
One of the differences between building in VS and command line is that a WPF build in VS defaults to <AlwaysCompileMarkupFilesInSeparateDomain>true</AlwaysCompileMarkupFilesInSeparateDomain>.
Outside of VS, the default is false.
We're likely changing this to default to True for VS or MsBuild (command line) scenarios for .NET 4 beta2.
If you need to, you could add that property directly to your .csproj or .vbproj.
(WPF Forum thread about this.)
10 minutes of what is coming in WPF4 on Channel9 got posted today. Jaime talks with Ian/Kevin. Going to watch now…
Rob commented on the beta 1 announcement post:
- "So, are you saying, you created Xaml2009, but we can't actually use it with VS or Blend until post .NET 4.0? And are you saying that we can't write applications with it without writing some bootstrapping code, because it currently doesn't compile to BAML + IL? Can you elaborate please."
Yes, when VS 2010 and .NET 4 ship, VS 2010 (Cider designer + XAML editor), Blend, Silverlight, and WPF's BAML won't have support for the new language features yet. This isn't ideal, but is the best we could do in this timeframe.
The major accomplishments that we have achieved in .NET 4 is:
- having one consistent XAML stack that is shared in WPF/WCF/WF (and beyond)
- moving XAML lower in the stack, out of WPF assemblies, into an assembly that depends on MsCorLib, System, System.Xml. In Beta1, it still depends on WindowsBase.dll, we hope to do some type forwarding (of ContentPropertyAttribute, etc...) from WindowsBase.dll to System.Xaml.dll in the next beta.
- moving WPF to 1 parser, instead of 3...it used to have seperate code paths for template, styles, and other parsing. Consistent behavior everywhere!
- creating a public API for BAML Reading, enabling analysis of XAML or BAML with the same API. ("BamlReader as Text" mode should be available next beta, it didn't make beta1.)
- ...
We had intended to enable BAML for the new language features, but "flipping" WPF/WF/WCF to all use the new stack ended up taking more work than we thought. Once WPF was flipped, we realized we also had significant perf work to do...as BAML in v3 avoided reflection, and we weren't doing that yet.
WPF 4 users will be able to use all of the XAML2009 lanugage features if they change the build action from Page to Resource. This will avoid compiling the XAML into BAML/IL. Events can still work in this scenario...Button Click="foo" looks for a "foo" method on the root object, so put a Window1 class at the root. We'll work on a sample.
We'll be working across all those groups to get support as soon as possible after .NET 4.
I understand that this fact makes it harder for WPF users to be excited about the new language features...
 | On May 20th, 2009, Beta 1 of .NET FX 4 and Visual Studio 2010 will be available for download1. We’re very excited that XAML2009 language features & System.Xaml.dll are now finally available for you to try. We first talked about XAML2009 & System.Xaml.dll at our PDC 2008 talk about XAML in November 2008 (video online). I’ve also shared a few status updates along the way: December, January, February, & March. |
Now that you can get the bits, we are very excited to hear your feedback, and we have much to share…
Of course, we continue to be excited about the 8 Benefits of XAML for UI and Beyond and are interested to see where you may find good uses of XAML. The investments we are making in .NET FX 4 and beyond should open up many new scenarios for XAML.
1 If you are an MSDN subscriber, everything was downloadable on May 18th.
Let’s Dive In!
Here is a list of some of the topics we’ll soon explore with you via blog posts, links, and samples:
XAML Users - XAML2009 Language features
Note: To use these new language features in WPF 4, you’ll need to avoid compiling your XAML, and use the existing XamlReader.Load(). XAML compiled to IL+BAML doesn’t support XAML2009 in the .NET 4 timeframe.
Type Developers
- Learn how your CLR type metadata, attributes, and interfaces affects your XAML capabilities (XamlType/XamlMember)
- TypeConverters and MarkupExtensions can get additional services (via IServiceProvider.GetService) during XAML load in v4, which will enable many new scenarios.
High Level APIs to Load/Save XAML
- System.Xaml.dll’s APIs: XamlServices.Load()/.Parse()/.Save()/.Transform() – apis to load and save XAML without any framework specific behaviors.
- PresentationFramework.dll’s APIs: XamlReader.Load()/XamlWriter.Save() – continues to do WPF specific things due to understanding of DependencyProperty, WPF Navigation, f:Freeze, and more.
- System.Activities.dll’s API: WorkflowXamlServices.Load()– quickly load WF workflows, including support for DynamicActivities + loading of the appropriate assemblies.
Lower Level APIs in System.Xaml.dll
- XamlReader/XamlWriter abstract base classes
- Writing a XAML Node Loop: while (reader.Read() { writer.WriteNode(reader);
- Core Readers/Writers:
Around the .NET Framework – a tour of frameworks uses of XAML
- WPF use of XAML (& BAML) – compatibility + new capabilities
- WF use of XAML
- WCF use of XAML
Other XAML Scenarios
- XamlPad – building a better XamlPad (support events, etc…)
- XamlDOM – showing off a sample DOM inside the XamlT.Pad sample
- XamlToCode – discussing the XamlToCode tab inside the XamlT.Pad sample
- Static analysis of XAML – writing an FxCop rule that analyzes XAML (or BAML in next beta)
- Validation of XAML – using the XamlXmlReader for validation
- Writing a “WrappingXamlReader”
- Constraining types/members available in XAML with a custom XamlSchemaContext
- Write a file format converter to/from XAML
- Building a new file format/storage mechanism for XAML – Build your own XamlReader/XamlWriter
Post .NET 4 Work
- WPF MarkupCompiler, BAML, Visual Studio, Blend support for XAML2009