Wednesday, April 14, 2010
Windows Presentation Foundation 4 Plumbing and Internals
Come get the inside scoop on how Windows Presentation Foundation (WPF) powers all its rich services – like layout, databinding, and animation. There is a lot of heavy lifting done for you under the hood; in this session, we crack open these system components, including the trees (visual, logical, and inheritance), the property system and its change notification, and a few of the routing systems that all messages go through. Bring your hard-hat for this one!
Demystifying the processes of initialization and binding.
Logical and visual inheritance in WPF 4.
How to improve application responsiveness in WPF 4.
Moving tasks into the background.
Other resources and a brief Q&A session
Welcome to session WPF4 Plumbing and Internals, we'll be diving into it shortly, but, this is the last day of PDC. Have you gotten a lot out of it so far? Fantastic!
Wide awake? I know it is a tough time slot at least I didn't have the first thing in the morning on the final day. That can be really rough.
My name is Blake Stone, I'm an architect here at Microsoft, working on a wide variety of .NET things. Really happy to be able to talk to you about the wpf side of things today. But when we thought about plumbing and internals, there are a couple of ways to go about a subject like this.
One of them is to really dive in and tell you all of the inside scoop. How all the comments are writtin in iambic pentameter. How every single variable has to rhyme with some other variable in the same file. But those are the kinds of things that are interesting to us, so the poetry of wpf will have to remain hidden for now. Instead, we're gonna focus on what's of interest from your perspective.
So this whole question of "when my properties are set" is a pervasive theme. If we think about it, in some ways it's kind of a trick question. If I ask "when is this prperty going to get set?", well a lot of properties never get set at all and so the classic phrase here, thank you very much to members of the WPF team for suggesting, these properties are sought. If I have an inherited property, if I have a property in a style, these things never get set at all.
And so look at the collection of methods that are available to me. SetValue() only gets called if I have a local value set, if I have a local binding, if I have an explicit local value. GetValue() is not really a parallel to that, it doesn't get the local value, what it gets is the effective value, where the effective value is the result of walking a chain of possibilities.
It might be that my property is animated, in which case I get the current animated value. It might be that I have a local value set, if no animation is going on, that's what I'll get. If that's not present, we'll look at triggers in styles. They take precidence over other setters in styles. If they're not present, we'll look at the style. From there, if it's not present, we'll actually walk up and look potentially for inherited values for inherited properties.
So it's possible that it comes from a wide range of places, and you should not count on SetValue() being called, because that's only the case for your local value being set.
In the case of styles and animations, literally never happens at all.
New feature in WPF 4, though, there are times when it would be really handy to temporarily change the value of a property without actually replacing its local value.
Let's have a look at a specific case in this application where that would be incredibly handy.
Thinking about inheritance, though, we talked about inheriting data contexts, and inheritance is one of those other topics where people get caught up a lot. Specifically, it's a question of what the logical tree is, what the visual tree is, and then what some people refer to as the inheritance tree. There really isn't an inheritance tree as we'll see just in a sec. The issue is that what inheritance comes from isn't strictly the logical tree, it isn't strictly the visual tree, it's kind of a hybrid of the two and in some cases it isn't related to either. So we'll walk through and think about that.
Look at the example code that we have here, and what we have is a grid that contains a button that's templated. The button contains a text block. And so, the logical tree is the containment order. The grid contains a button, the button contains a text block. The template is set on a property of the button, it's not actually contained in the button, so it's not part of the logical tree. So the blue here really represents the logical tree.
However, it's not that the template isn't involved at all in figuring out what's presented. In fact, it's very much involved. When we actually go ahead and run this code, during layout this template is going to get expanded. Our visual tree will actually have a few other elements in it, here. We get a content presenter inside a stack panel so that the text block can actually be properly presented on the button.
What's interesting in this case is that we have now potential confusion about where my data context comes from. The stack panel has a data context that got inserted for me between the text block and the button. The grid also has a data context, so where does it come from? The answer is, the inheritance is designed to not suprise you.
If somebody were to come along and create a new template, and inject a bunch of visuals and change the data context under you, it would surprise the author of the original XAML. This is a rare case where the template's actually embedded inline. Usually, you get it from somewhere else. It may be part of the system resource, what have you.
So, what we do instead is when you're actually trying to inherit properties, first we will look for the logical parent, and we will track the logical parent in preference to anything else when looking for an inherited property.
The ideal approach would be for me to actually learn about threading. And doing all the threading work yourself is kind of a pain. There's a lot of setup that you need to think about, there's a lot of communication back and forth between the threads, but BackgroundWorker does an awful lot of the work for you. And so for trivial cases, BackgroundWorker's a great way to go.
What you wind up with is the UI thread where all of the sort of mainline WPF things go on. WPF has it's own render thread that you really don't need to worry about that tries to offload some of the raw rendering tasks to another thread for some parallelism. But BackgroundWorker creates a whole new set of threads so that if I'm doing a bunch of operations it will manage a pool of threads for me. It worries about how many threads are optimal for my hardware. I don't need to think about that at all. And what runs on those worker threads is my code. I get to define everything that runs there. WPF isn't involved, so I have free reign.
It's great for these kind of long-running or blocking operations. But, you should think about this. DispatcherObjects and anyhthing else that's connected to WPF are sort of off-limits from your BackgroundWorker code. And what's a DispatcherObject? Well in WPF, everything is a DispatcherObject, right? You get into visuals, you get into FrameworkElements, you get into Brushes, you get into Freezables. Everything is a DispatcherObject, which means it's got tight affinity to a single thread, the UI thread in this case, and you can't use it anywhere else.
Virtualization is a wonderful, wonderful technique. I highly recommend it. In practice there are a bunch of ways of dealing with this. The root question is "why am I bothering to create all of these visuals that aren't actually going to be displayed? why am I loading all of the images to create all of these thumbnails when they're not actually going to be used?"
Virtualiziation is basically a slight-of-hand mechanism, and if you've got a long scrolling list or you've got an enormous table that you want to scroll around, virtualization says I'm only going to create the things that I actually need to create the display that's on the screen at the time.
Luckily, a lot of things do this automatically. ListBox virtualizes by default, so does DataGrid, which you may have been using from the toolbox in 3.5, but honestly is a WPF4 new feature.
The way I deal with this is in my control, I need to make sure that anything that creates a bunch of items uses an appropriate panel. And so there's an ItemsPanelTemplate that allows me to define what panel is going to be used. I've just got a list in mine, so what could possibly have gone wrong?
Multi-Touch on Microsoft Surface and Windows 7 for .NET Developers
Multi-touch is going mainstream as part of Microsoft Surface and Windows 7. Come to this session to learn about how to create innovative new user experiences with touch – and how .NET developers can share code between both of these platforms. You’ll get a deep dive on the new touch capabilities in WPF 4 and the subset in Silverlight 3. You will also see how the unique capabilities of Microsoft Surface take multi-touch to a whole new level.
An overview of multi-touch technology.
How Microsoft Surface and WPF interact.
Touch capabilities in WPF 4.
Multi-Touch on the web using Silverlight.
Multi-Touch manipulations and manipulation containers.
Inertia behaviors, manipulation events, and an intertia demo.
Touch panning demo and support.
Surface's extensions of WPF
Toolkit and SDK
Surface toolkit for Windows Touch and surface SDK features for multi-touch.
More about the capabilities of Surface, beyond just multi-touch.
Development roadmap for Windows Touch.
Resources, conclusion, and Q&A
New Developer Tools in Windows Embedded Standard 2011
See how Windows Embedded Standard 2011 fuses the power and functionality of Windows 7 with the flexibility and workflow needed for the embedded developer to make devices come to life. Discover 2 distinct development experiences, Image Based Wizard v. Image Configuration Editor, and explore the workflow for creating an embedded device with Windows Embedded Standard 2011.
Windows Embedded Family
An introduction to the family of Windows Embedded products.
Standard 2011 embedded developer toolkit.
Image building blocks.
The image building process and a demo of the image builder wizard.
Image configuration and a demo of the image configuration editor.
A brief Q&A session, and the wrap-up of the discussion
Custom Behaviors for Advanced Microsoft Silverlight UI Effects
Learn how to light up your Silverlight application by using behaviors to add physics-based animation and rich interactivity. Hear tips and tricks on how to create advanced behaviors, techniques to make them extensible, and how they can be integrated to create immersive applications and enhance interactive games.
Goals and reasons for using custom behaviors.
Triggers, Actions, and Behaviors
Triggers, actions, and behaviors. Demonstrations.
Using easing functions.
Visual State Manager
How to use the Visual State Manager.
Ripple click, explode click, and other features.
Links to other resources, conclusions, and a brief Q&A session.