At PDC09, we discussed that our direction was to invest in improving the Silverlight XAML parser. We didn’t announce a timeframe, but I’m happy to see that this work successfully made it in time for Silverlight 4!
David Poll, the Program Manager for Silverlight runtime’s XAML parser, goes into the details of what is new and improved in “New in the Silverlight 4 RC: XAML Features”.
There is still a lot of great work to do in future Silverlight versions - but this is a great foundation to build on!
Developers often find some benefit by implementing an override for ToString(). I believe that we could make providing a DataTemplate in generic.xaml very beneficial as well. First we have to start a beneficial cycle…
What could be done with it:
- Apps that use that object in their UI, would have a default data template.
- Tools that help build UI could have a better default data template.
- Visualizers of generic object graphs (like debuggers) could have a better visual representation.
- more…
How to create a default DataTemplate for your type:
- Start with a WPF or Silverlight Control Library project
- Create the class in that project
- Modify themes\generic.xaml to contain a DataTemplate with DataType=”{x:Type l:MyType}”
- (Silverlight doesn’t yet support this…so perhaps you could give your DataTemplate a key of “defaultViewForMyType”)
Thoughts?
Would love to hear what you think…
Thanks to vocal feedback, we’ve realized that our text clarity improvements in VS 2010 Release Candidate could be improved upon again.
Chipalo gives you details in the WPF Text Blog’s: “Additional WPF Text Clarity Improvements”
I’m very happy to see this problem with smaller text sizes fixed!
Happy to see that we’ve finally released a few key facts on Windows Phone 7’s developer platform:
Mix10 in Las Vegas, March 15-17th will be digging deep into the details. I’m excited…XAML UI on the phone!
Yesterday I was in a meeting with the MultiPoint team here at Microsoft and I was very excited to hear that they helped release a new SKU for Windows Server called Windows MultiPoint Server 2010! See microsoft.com/windows/multipoint
My vision was having 2 keyboards and mice on 1 pc on a desk, and supporting the ability to have users use 2 different applications.
June 2007, I blogged:
I'd love to have 2 monitors, 2 mice and 2 keyboards on a pc to enable 2 users.
Unfortunately, Windows client has a bunch of ties to 1 app having focus, etc… MultiPoint Server gets around this by effectively using Remote Desktop sessions into the same computer. So you have 2 monitors, 2 keyboards, 2 mice and you are good to go. Sounds like you can do many more users than that, as well…
Interesting!
During WPF 4, the WPF team did a bunch of work with the Visual Studio team to ensure that VS (and thus all WPF apps) worked as well as possible over Remote Desktop.
Jossef Goldberg, a WPF Program Manager, has a great blog post that goes into great detail: “Optimizing Visual Studio 2010 and WPF applications for Remote Desktop”
[Other Terms: Terminal Services, TS, Remote Desktop Protocol, RDP]
Rob Update – Looking forward
I’m still spending time on .NET 4/VS 2010, but since January, I’ve also been doing more forward looking thinking. We have a long list of important things to do…I’m itching to engage on several fronts…lots of good stuff to do.
Fun times!
WPF: Feature Suggestions
- There is a WPF Feature Suggestions site now! You get 10 votes…don’t waste them before you see all the ideas. We’re about to ship what I think is a great WPF 4 release…and we’re taking this opportunity to connect with you, the XAML UI heads out there, to understand your wishes, needs and priorities. Vote early, vote often!
Tools: WPF & Silverlight Designer in VS 2010
XAML: XAML for Config
Windows Phone 7 Series
.NET Framework
Setup: WiX
- Excited to see Rob’s announcement. I, too, like numbers like 11, 22, 33, etc… Happy belated 33rd bday Rob…and I’m happy about your new day job.
- WiX v3.5 supports VS 2010 RC -- Read about the “Harvest” feature (point #3 in Rob Mensching’s post)
Data/Modeling
I met Simon Ferquel this week at the 2010 MVP Summit. I gave a talk about XAML on Wednesday, and later that day blogged one of my samples from the talk: “XamlSchemaContext/XamlType/XamlMember – a command line example”.
He commented on that post with:
Hi Rob,
As I understand, creating a custom XamlSchemaContext could be a way to make Xaml content integrate with an IoC, isn't it?
I can imagine a scenario where you can then write something like :
<Foo>
<Foo.Bar><IBar /></Foo.Bar>
</Foo>
With IBar being an interface that is resolved by the IoC. Same thing could apply with types without default constructor whose dependencies could be injected by the IoC-enabled schema context.
If you confirm that it is doable, I'll make a sample of a Unity-enabled Xaml Schema Context.
by Simon Ferquel
Turns out that subclassing XamlSchemaContext and XamlType seems to have worked quite nicely. See Simon’s “[Xaml] IoC-enabled Xaml parser” The basic idea is the custom schema context returns a XamlType for IBar that says it knows how to be created. When the XamlObjectWriter calls it to create the IBar, it can find an appropriate IBar to return.
Other Approaches
Other people have accomplished Invesrion of Control other ways…
- John “Z-Bo” Zabroski uses a custom markup extension. (via comment)
- I’ll add more links as I find other approaches or comments mention them.
Today at MVP Summit 2010, one of the things I discussed with the MVPs was the concept of XamlSchema. To leverage my already done work, and to share with all of you, my XAML friends, I’m following up my talk with a post that goes into that area.
All XAML systems have a way that they figure out XamlSchema. [MS-XAML]’s section 3 is “XAML Schema Information set” which defines Schema, XamlType, and XamlMember. .NET 4’s XAML stack exposes a set of apis that closely mirror that information about types and members.
XamlSchemaContext
A XamlSchemaContext is the object that retrieves (and usually caches) type/member information for the purposes of understanding XAML behavior for Load or Save or other.
There are 3 interesting flavors of XamlSchemaContexts today:
- WPF optimized context: XamlReader.GetWpfSchemaContext() – These XamlTypes/XamlMembers are optimized to avoid reflection in many cases for type/member information and for actions like “New”, “Set”, “Get”, “Add”, etc…
- General purpose .NET context: new XamlSchemaContext() – These XamlTypes/XamlMembers are built on top of Reflection APIs for type/member information and for actions like “New”, “Set”, “Get”, “Add”, etc…
- Silverlight context: new SilverlightSchemaContext() //from XamlToolkit - code.msdn.com/xaml - These XamlTypes/XamlMembers are built on top of Reflection APIs for type/member information and for actions like “New”, “Set”, “Get”, “Add”, etc… (but they know that the Silverlight has a subset of “XamlTypeInformation attributes and interfaces” that .NET Framework has – and adapt. For example ContentPropertyAttribute in .NET 4 is in System.Xaml.dll, but it is in System.Windows.dll in Silverlight 2-4.)
Goal for XamlSchemaContext
Have one way for XAML systems to understand XamlSchema for types. Have one way for XAML systems to provide XamlSchema in other type systems (CLR, Silverlight, NativeCode, JavaScript, Java, etc…)
Some Scenarios for XamlSchemaContexts
Given a XamlSchemaContext, there are a few interesting things that you can do with it:
Code Sample
I’ve posted this project at http://robrelyea.com/demos/xamlSchemaExplorer
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Windows.Markup;
5: using System.Xaml;
6: using System.Text;
7:
8: namespace XamlSchemaExplorer
9: {
10:
11: public class Program
12: {
13: static void Main(string[] args)
14: {
15: XamlSchemaContext schemaContext = new XamlSchemaContext();
16: XamlType xamlType = schemaContext.GetXamlType(typeof(SampleClass));
17:
18: StringBuilder sb = XamlUtilities.GetStringRepresentationOfXamlType(xamlType);
19: string output = sb.ToString();
20: Console.WriteLine(output);
21: }
22: }
23:
24: #region SampleClass class definition
25: [ContentProperty("Bar")]
26: public class SampleClass
27: {
28: [TypeConverter(typeof(BarConverter))]
29: public bool Bar { get; set; }
30:
31: public int Foo { get; set; }
32:
33: public string Baz { get; set; }
34:
35: private List<int> _integers;
36: public List<int> Integers
37: {
38: get
39: {
40: if (_integers == null)
41: {
42: _integers = new List<int>();
43: }
44: return _integers;
45: }
46: }
47: }
48: #endregion
49:
50: #region TypeConverters
51: public class BarConverter : TypeConverter
52: {
53:
54: }
55: #endregion
56:
57: public static class XamlUtilities
58: {
59: public static StringBuilder GetStringRepresentationOfXamlType(XamlType xamlType)
60: {
61: StringBuilder sb = new StringBuilder();
62:
63: sb.AppendLine(xamlType.Name);
64: XamlMember contentProperty = xamlType.ContentProperty;
65:
66: foreach (var xamlMember in xamlType.GetAllMembers())
67: {
68: sb.AppendFormat(" {0} {1} {2}\n",
69: xamlMember.Type.IsGeneric ? XamlUtilities.GetGenericName(xamlMember.Type) : xamlMember.Type.Name,
70: xamlMember.Name,
71: xamlMember.IsReadOnly ?
72: " { get; } " : " { get; set; }");
73: if (xamlMember.TypeConverter != xamlMember.Type.TypeConverter)
74: {
75: sb.AppendLine(" ** Converter is " + xamlMember.TypeConverter.Name);
76: }
77: if (xamlMember == contentProperty)
78: {
79: sb.AppendLine(" ** This is the ContentProperty");
80: }
81: }
82: return sb;
83: }
84:
85: public static string GetGenericName(XamlType xamlType)
86: {
87: string typeName = xamlType.Name;
88: typeName += "<";
89: int typeArgCount = 0;
90: foreach (var typeArg in xamlType.TypeArguments)
91: {
92: if (typeArgCount > 0)
93: {
94: typeName += ",";
95: }
96:
97: if (typeArg.IsGeneric)
98: {
99: typeName += GetGenericName(typeArg);
100: }
101: else
102: {
103: typeName += typeArg.Name;
104: }
105: }
106: typeName += ">";
107: return typeName;
108: }
109: }
110: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
This outputs the following to the command line:
1: SampleClass
2: Boolean Bar { get; set; }
3: ** Converter is BarConverter
4: ** This is the ContentProperty
5: Int32 Foo { get; set; }
6: String Baz { get; set; }
7: List<Int32> Integers { get; }
8:
9: Press any key to continue . . .
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Would love to understand your questions/issues
Please let us know what you think…
Interesting to see “From NetReflector to XAML” from Craig Sutherland detailing an exploration of using XAML for Config for CruiseControl.NET.
WPF’s XamlReader.Load vs System.Xaml’s XamlServices.Load()
CS: “although from what I understand WPF will still have its own implementation”
RR: WPF 4’s API XamlReader.Load’s goal is to be compatible, yet better, than the WPF 3 version of XamlReader.Load. This call does some special things for WPF (see Mike Shim’s “Use XamlReader.Load for WPF XAML (not XamlServices.Load)” for details. For Config scenarios, XamlServices.Load/Save would be ideal…that is what I do wth XamlPadSample as detailed in “Persistable View Models & XAML for Config”
Representing Time
Craig shows the use of a markupextension for Time: {Time 5} or {Time 30, Unit=Minutes}, etc…
A few options to consider (for Interval.Period, SubVersion.Timeout, Project.ModificationDelay, etc…) would be:
- Keep using the {Time} markupextension. Decent readability…
- Make those properties of type TimeSpan, which has a type converter that will convert to/from a string – see DoubleAnimation.Duration, for example:
<DoubleAnimation Storyboard.TargetName="MyAnimatedRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" />
- Keep those property of type Int32, but use a “A Type Converter Declared on a Property” (see “Strings to Things (or How XAML interprets Attribute Values”) to introduce a TypeConverter than knows how to convert a string representing a time to integers. Similar approach allows UIElement.Height/.Width use “1in”, “96px”, etc…
Robby Ingebretsen, nerd + artist extraordinaire, just blogged a bit about his plans for taking Kaxaml forward in the WPF 4 and Silverlight 4 era: “Kaxaml Update + Downloads + A Request”
He and I had a good chat last week over his plans and some of the ways that .NET 4 can help XAML focused tools for .NET or Silverlight better.
Should be very fun!
I always enjoy understanding Don’s perspectives. This InfoQ interview is interesting as always. Touches on SOAP, XML, XML Schema, M, etc…
InfoQ: Don Box Discusses SOAP, XML, REST and M
Is XML as bad as Don is saying to you?
We can explore other ways to write down the XAML data model (O-M-V + TypeInfo)… John Gossman prototyped JAML (John’s Application Markup Language) the other week with .NET 4’s XAML stack.
if XML isn’t the right thing, we are not stuck with XML…
XAML has a major problem in v3 that we’ve addressed with a hotfix last year and .NET 4 includes the fix as well.
From KB 968227 article:
Consider the following scenario:
- You have a computer that uses the English (United States) regional settings.
- In the Regional and Language Options item in Control Panel, you customize the List separator character in Customize Regional Options dialog box .
- You create a Windows Presentation Foundation (WPF) application.
- The application creates a CultureInfo object for the English (United States) culture before WPF starts rendering.
When you start the application, an exception is thrown by the Extensible Application Markup Language (XAML) parser, and then the application crashes.
…
Pausing to think about next steps after making strong progress in the “Exploring: XamlPad to XamlDesigner” journey in the last 10 days. 3 major things from that Exploring post that haven’t been tackled in XamlPadSample include: Silverlight support, Designer support, and Editor richness.
I’m going to explore Designer support options with this post.
I had originally sketched out this area as:
XAML Step: PropertyGrid, Selection Model, SourcePreservation
- Simple Property Grid
- Selection model enabling selection in View surface or Xaml editor, and synchronized editor.
- Source preservation of XAML with XamlDom based store
But now I’m realizing there may be a few different directions that people may want. This may be because different domains (UI, Workflow, etc…) or different users types (UI Developers, UI Designers, WorkFlow modelers, etc…).
Approaches to XamlDesign Surfaces
View only – never show XAML
A customer recently asked an associate of mine for a WPF hostable designer with a View Only Design surface. This would require a toolbox, interactions to add, move and remove controls, and ability to change values (either with a property grid or “on object” manipulations). Source code preservation may or may not be important in this scenario. Should XML comments be preserved? How about white space?
View or XAML – but never both at the same time
In VS2010 & .NET 4, Windows Workflow Foundation (WF) provides this View or XAML design experience.
View and/or XAML - splitview with interactive view
VS (via “Cider”) and Blend both offer a fully functional split view, with an interactive design canvas + property grid, and an editable XAML pane.
XAML with Preview
XamlPads offer a View which is a preview mode, and an editable XAML pane.
XAML Only
This sounds like notepad. :-) (but maybe you could have notepad with intellisense)
What is your ideal? For UI, workflow, data, other?
Would love to hear thoughts on these various approaches.
For UI, is splitview the preferred model for devs and designers? Or does the XamlPad approach (XAML with Preview) have merit?
For Workflow, are people happy with View or XAML, but never both at the same time?
Any thoughts or feedback in this space?
3 major features added to XamlPadSample today! Including Alternate Views, which has not been done in any XamlPad or XamlDesigner that I’m aware of. (link to previous posts/overview & sample code available via XamlPadSample)
App.xaml Support for {StaticResource}
View pane now shows result of {StaticResource} or {DynamicResource} resolution of resources from app.xaml. Shown loading Welcome.xaml from Family.Show v3.
Assembly Loading
XAML files which include uses of classes from local: or other custom types in project class libraries now load. Shown loading PersonInfo.xaml from Family.Show v3. (note, XamlPadSample doesn’t ever call build on your project/solution.)
Alternate Views
The AlternateViews feature enables you to put something more useful in the “white blank pane” of a non-UI rooted XAML file.
Below you can see a crude UI representation of BlackResources (from Family.Show v3) showing many brushes, DataTemplates, Styles that were defined in a ResourceDictionary.
The sample also contains a simple visual representation for App.xaml and XamlPadConfig.
Detailed notes from Backlog.txt in sample code:
---------------------------------------------
2010/01/30 - posted v1f - Alternate View, app.xaml, and assembly loading
---------------------------------------------
Implemented: {StaticResource foo} will now resolve to resources in the current page or in the ApplicationDefinition xaml file (matched Blend/Cider feature)
Implemented: Assemblies from a project will now be loaded (matches Blend/Cider/XamlCruncher feature)
Implemented: Provided the start of a mechanism to provide alternate views for non-visual root elements. Lots of potential here...
XamlPadHelpers project
•ResourceProxy.cs (NEW)
◦Added ResourceProxy, a ContentControl - to hold a pointer to the App.Resources for a project. We inject this element during the parse as the real root of the tree we are building.
This enables {StaticResources } that we parse to find resources delared in App.xaml or in a merged dictionary as well.
•AssemblyData.cs
◦In v1e, I had plumbed this class to find the right assembly. Now there is a Load() method a property of type Assembly to store the loaded assembly.
•ProjectData.cs
◦Added a ContentProperty for <ProjectData> - the AssemblyReferences property. Doesn't change the functionality of Pad.config.xaml, just the conciseness.
◦Added an ApplicationResources property which will load the corresponding app.xaml and grab the .Resources property from it.
•View.cs (NEW)
◦New class to track a Type->TemplateUri mapping. This is effectively a Dictionary, but notice the [DictionaryKeyProperty("Type")] on the class, which enables avoiding x:Key in the XAML.
This is the same (now v4 public feature) that Style, ControlTemplate, and DataTemplate use to avoid needing a x:Key by default.
•XamlEngine.cs
◦LoadObjectsForDesign now has an appResources property, and will inject a new ResourceProxy(appResources) as the root object in the tree if appResources is not null.
◦new LoadXamlDocument routine that will use CreateReader() and LoadObjectsForDesign()
◦new LoadXamlDocumentWIthAppResources routine that will use CreateReader() and LoadObjectsForDesign(), and it will pass in appResources into LoadObjectsForDesign if we know
of the app.xaml
•XamlPad.xaml.cs
◦XamlText_TextChanged() enhanced to attempt to load each assembly of a project before parse.
◦XamlText_TextChanged() enhanced to wire in alternate Views (via XamlPadConfig.Views mappings) for any non-UI root objects displayed in XamlPad.
TODO: wouldn't mine cleaning up this code...I think I changed error experience badly...
•XamlPadConfig.cs
◦Added the Views property for the alternate views feature.
•XamlPadHelpers.datatemplates.xaml (NEW)
◦Added several DataTemplates that provide basic visual representations for object graphs that have the following roots: Application, ResourceDictionary, XamlPadConfig
Pad project
•MainWindow.xaml.cs
◦Added 3 default Views to plug into the default Pad.config.xaml (for AlternateViews feature)
Next page »