2-776.pptx

XAML Case Study: Putting it All Together, Office and XAML

1.0x

2-776.pptx

Created 2 years ago

Duration 0:00:00
lesson view count 1813
XAML Case Study: Putting it All Together, Office and XAML
Select the file type you wish to download
Slide Content
  1. Jason Morse

    Slide 1 - Jason Morse

    • Principal Engineering Manager
    • Office Core Experience Team
    • Putting it all together, Office & XAML
    • XAML Case Study: Putting it All Together, Office and XAML
    • 2-776
    • Andrew Coates
    • Senior Software Engineer
    • Office Core Experience Team
    • //build/ content is being presented by Microsoft Office Mix The video for this session will be available shortly
  2. Office values and goals

    Slide 2 - Office values and goals

    • Approach to universal applications
    • Where we are today
    • Agenda
  3. How do you use XAML if you don’t care about easy?

    Slide 3 - How do you use XAML if you don’t care about easy?

  4. Slide 4

    • There are many adjectives people use to describe Office…
    • Functional, powerful, productive, feature rich, complicated…
    • Fast and light are not usually among them.
    • First a bit of background on Office
  5. All native, mostly C++

    Slide 5 - All native, mostly C++

    • Hails from pre-C++ days over 30 years ago.
    • Continues to evolve with rapid adoption of C++11.
    • It has grown progressively in that time
    • Up to about 171 million lines at last count .
    • Not just Word, Excel, PowerPoint anymore.
    • Most versions on other platforms have been forks
    • These aren’t included in the 171 million lines.
    • The Office codebase
  6. Originally we sold Office for machines.

    Slide 6 - Originally we sold Office for machines.

    • Increasingly we are selling to people.
    • What does this mean?
    • Available wherever you are.
    • Consistent experience.
    • New features need to roll out everywhere.
    • The business has changed
  7. Changing the adjectives

    Slide 7 - Changing the adjectives

    • Fast & fluid
    • Still powerful
    • Sharing code
    • Leveraging what we have for new platforms.
    • Maximize code sharing between platforms.
    • Still use enough platform specific code to guarantee the best experience possible on that platform.
    • We do care about development speed…
    • But complex and expensive solutions are fine as long as we can centralize them.
    • So what do we care about?
  8. Traditional databinding is too slow.

    Slide 8 - Traditional databinding is too slow.

    • Set data into controls in code-behind.
    • x:Bind does a great job of addressing this, use it!
    • Don’t make every property a DP.
    • Custom DependencyProperties are significantly slower than built-in ones.
    • Use only as many elements as you need.
    • Collapsed trees still have cost.
    • Either load optional elements dynamically or use x:DeferLoadStrategy.
    • Previously VSM would create extraneous DependencyObjects.
    • Don’t be afraid of code-behind!
    • Using XAML at the speed of light
    • In the Windows 8.1 timeframe we looked at how we could squeeze every ounce of performance out of XAML.
  9. So {Binding} is not super fast

    Slide 9 - So {Binding} is not super fast

    • When we started x:Bind did not exist
    • Push data into XAML using code behind
    • Code behind can interact directly with native C++ types
    • Wanted a binding replacement to help write repetitive code-behind
    • How we work with data in XAML
  10. We call this XAML scripting

    Slide 10 - We call this XAML scripting

    • Preprocess the XAML file during a pre-build step
    • Custom XAML markup defines:
    • Properties.
    • “Scripts”, to push data into the XAML elements.
    • Define when each script should run.
    • Generate code-behind from the markup
    • XAML team used same concept for x:Bind design
    • A solution based on custom XAML markup
  11. Slide 11

    • <o:Property Type="Unicorn" Name="User"/>
    • <o:Script Trigger="User.Name">
    • tb->Text = User->Name;
    • </o:Script>
    • <TextBlock x:Name="tb" />
    • Roughly the same as:
    • <TextBlock Text="{x:Bind User.Name, Mode=OneWay}"/>
    • A quick glimpse at Office’s XAML scripting
  12. The Good

    Slide 12 - The Good

    • Similar performance gains as we can now get from x:Bind.
    • Switching yielded 50% faster boot for Calendar.
    • Unintended side effects
    • Meant to be just for pushing data.
    • Too easy to write logic in the UI.
    • Logic becomes platform specific.
    • Hard to unit test.
    • Scripting side-effects
    • Sometimes what happens and what you think will happen aren’t quite the same.
  13. Business logic should be separate from UI code

    Slide 13 - Business logic should be separate from UI code

    • Always been important.
    • Even more so in todays cross platform world.
    • Encapsulated in its own object
    • The UI can communicate directly with this object.
    • Object to UI communications should be through events.
    • This allows the object to be shared
    • Metapoint on how to build UI
  14. Model defined in a markup language.

    Slide 14 - Model defined in a markup language.

    • Generates a base class and platform specific interop layers.
    • Developer fills in ViewModel implementation.
    • Moving to markup generated ViewModels
    • Model Definition
    • Generated
    • ViewModel
    • XAML Interop
    • (INPC)
    • JNI Interop
    • iOS Interop
    • iOS UI
    • XAML UI
    • Java UI
    • Unit Tests
    • MDL
    • Generated Base
    • Interop Layers
    • Platform Specific UI
  15. Great for XAML to C++ interop

    Slide 15 - Great for XAML to C++ interop

    • Makes writing code against XAML dramatically easier.
    • Generates winmd interfaces for you.
    • Has some drawbacks to be aware of
    • Can mask complexity or cost.
    • Some limits on how C++ can be integrated.
    • Not cross platform.
    • Works great as a thin interop layer
    • C++CX is the glue for C++ apps
    • Overview of C++CX pros and cons.
  16. Understanding C++CX classes

    Slide 16 - Understanding C++CX classes

    • public ref class Foo sealed
    • : public IBar
    • {
    • public:
    • // public class properties/methods
    • property int Number;
    • void FooMethod();
    • // Ibar method override
    • virtual void BarMethod() override;
    • internal:
    • void NativeMethod(CppModel* model);
    • private:
    • CppModel* m_model;
    • };
    • class Foo : public RuntimeClass<__IFooPublicNonVirtuals,
    • IBar>
    • {
    • public:
    • // __IFooPublicNonVirtuals interface methods
    • virtual HRESULT get_Number(int* num) override;
    • virtual HRESULT put_Number(int num) override;
    • virtual HRESULT FooMethod() override;
    • // IBar methods
    • virtual HRESULT BarMethod() override;
    • void NativeMethod(SomeCPPStruct* model);
    • private:
    • CppModel* m_model;
    • };
    • C++CX
    • C++ (using WRL)
  17. // some simple code…

    Slide 17 - // some simple code…

    • control->RenderTransform->X = 25.0;
    • // turns into
    • control->QueryInterface(IID_PPV_ARGS(pUIE.GetAddressOf()));
    • pUIE->get_RenderTransform(&pTransform);
    • pTransform->QueryInterface(
    • IID_PPV_ARGS(pTranslate.GetAddressOf()));
    • pTranslate->put_X(25.0);
    • // what’s so bad? Well…
    • If (control->RenderTransform->X != newTransformX)
    • control->RenderTransform->X = newTransformX;
    • If (control->RenderTransform->Y != newTransformY)
    • control->RenderTransform->Y = newTransformY;
    • Understanding what C++CX generates
    • It’s so easy! What could possibly go wrong?
  18. C++ types can be used natively in CX

    Slide 18 - C++ types can be used natively in CX

    • The issue is how to get those objects in the first place.
    • In the same binary it’s easy
    • Can call internal functions directly.
    • Across binaries it is harder
    • Calls out work so you can use a locator pattern.
    • Object^ can be typecast to IInspectable* via reinterpret_cast.
    • Exported setter functions are a pattern we use a lot.
    • __dllexport void SetModel(C^ c, const Model& m)
    • {
    • c->SetModel(m);
    • }
    • Using C++ types in ref classes
    • Main strategies for handling native types from within ref classes.
  19. Slide 19

    • Let’s say you have a C++ class you want to expose to x:Bind
    • class UnicornImpl
    • {
    • public:
    • void RegisterPropChanged(function<void(int)>&);
    • wstring GetName();
    • };
    • Composing C++ classes
  20. ref class UnicornCX : BaseINPC

    Slide 20 - ref class UnicornCX : BaseINPC

    • {
    • UnicornCX() : m_native(make_shared<UnicornImpl>)
    • {
    • m_native.RegisterPropChanged([=]( int propId) {
    • if (propId == idName)
    • NotifyPropertyChanged(“Name”);});
    • }
    • property Name {
    • String^ get {
    • return ref new String(m_native.GetName().c_str());
    • }}
    • shared_ptr<UnicornImpl> m_native;
    • }
    • Wrapping with CX
  21. How about if you really want to use full inheritance in C++?

    Slide 21 - How about if you really want to use full inheritance in C++?

  22. import “Windows.Foundation.idl”;

    Slide 22 - import “Windows.Foundation.idl”;

    • [uuid(…)]
    • [exclusiveto(Unicorn)]
    • interface IUnicorn : IInspectable
    • {
    • [propget] HRESULT Name([out, retval] HSTRING*v);
    • }
    • runtimeclass Unicorn
    • {
    • interface IUnicorn;
    • interface INotifyPropertyChanged;
    • }
    • With C++ first generate a header and winmd
    • Fun with SDK tools:
    • Make an IDL
    • Run it through midl /winrt to create a header and .winmd file.
    • mdmerge.exe allows merging with your own winmd files.
  23. class UnicornWRL

    Slide 23 - class UnicornWRL

    • : RuntimeClass<IUnicorn, INPCImpl, UnicornImpl>
    • {
    • UnicornWRL()
    • {
    • RegisterPropChanged([](int propId) {
    • if (propId == idName)
    • NotifyPropertyChanged(HStringReference(L“Name”).Get());});
    • }
    • STDMETHODIMP get_Name(HSTRING* value){
    • return HStringReference(GetName().c_str()).CopyTo(value);
    • }}
    • }
    • Now use WRL to inherit from your base class
  24. Use CustomResource loader

    Slide 24 - Use CustomResource loader

    • Can load resources from our existing resource pipelines.
    • As an example, for colors:
    • Background=“{OfficeBrush PaneBackground}”
    • becomes:
    • Background=“{CustomResource Brush.123}”
    • Preprocessing the XAML to put an int in the XAML saves us from doing string lookups at runtime.
    • We use this for string resource lookups, colors, command ID lookups, etc.
    • Integrating non-XAML resources
    • One of our earliest changes was creating a custom build tool to perform simple transformations on XAML files.
  25. inline IXamlType^ __XamlTypeInfo_CreateType_MyEnum(XamlTypeInfoProvider^ provider)

    Slide 25 - inline IXamlType^ __XamlTypeInfo_CreateType_MyEnum(XamlTypeInfoProvider^ provider)

    • {
    • XamlUserType^ userType = ref new XamlUserType(provider, L"MyEnum",
    • provider->GetXamlTypeByName(L"System.Enum"));
    • userType->KindOfType = Interop::TypeKind::Metadata;
    • userType->FromStringConverter =
    • [](XamlUserType^ userType, String^ input) -> Object^
    • {
    • uint32 enumValue = userType->CreateEnumUIntFromString(input);
    • return ref new Platform::Box<MyEnum>((MyEnum)enumValue);
    • };
    • userType->AddEnumValue(L"Option1", PropertyValue::CreateInt32(MyEnum::Option1));
    • userType->AddEnumValue(L"Option2", PropertyValue::CreateInt32(MyEnum::Option2));
    • return userType;
    • }
    • __XamlTypeInfoMap_IXamlType(L"MyEnum", __XamlTypeInfo_CreateType_MyEnum);
    • Why not put it all in an enum?
  26. Icon control is a UserControl with no XAML file

    Slide 26 - Icon control is a UserControl with no XAML file

    • All contents are generated via code.
    • Internals are abstracted from users.
    • We switched to colored fonts instead of images
    • Glyphs now support colored fonts and are more efficient than TextBlock.
    • This allows a single asset to support multiple sizes.
    • Can still use PNGs for targeted cases.
    • public ref class Icon sealed : public UserControl
    • {
    • public:
    • property uint16 Id { uint16 get(); void set…
    • property IconSize Size { IconsSize get(); void set…
    • };
    • Office Icon control
    • How we load icons for commands in Office.
  27. Icon lookup logic

    Slide 27 - Icon lookup logic

    • <core:Icon Id=“{= msotcidFoo}” Size=“{= ImageSize::Square20}”/>
    • <core:Icon>
    • Look up ID metadata
    • Use primary font
    • Use language specific font
    • control boot
    • Create
    • Glyphs
    • Create
    • Image
    • Get target image file
    • Insert in Icon.Content
  28. What about very custom UI?

    Slide 28 - What about very custom UI?

  29. Highly sophisticated, dynamic, animated, interactive content.

    Slide 29 - Highly sophisticated, dynamic, animated, interactive content.

    • Rendered using DirectX since Office 2013.
    • Content is rendered in 2d layers which are then composed.
    • XAML has a great solution here!
    • SurfaceImageSource, VirtualSurfaceImageSource and SwapChainPanel enable integrating DirectX content.
    • Can be transparently composed with XAML UI.
    • Allows for seamless animations and smooth scrolling.
    • Office document canvases
    • The architectural approach to the document canvases where fidelity of look and feel is absolutely critical.
  30. Application

    Slide 30 - Application

    • Thread
    • UI Thread
    • Compositor Thread
    • Rendering Cross Platform Architecture
    • Channel
    • WinRT Backend
    • XAML
    • Direct Composition
    • Channel
    • Android Backend
    • Java Views
    • Channel
    • In-Process Direct3D Compositor
    • iOS & Mac
    • Frontend talks directly with Core Animation
    • Core Animation
    • Win32
    • XAML
    • Android
    • iOS OSX
    • Shared C++
    • Layout
    • Rendering
    • AirSpace Frontend
    • Some Code Sharing
    • +
    • Platform-Specific Forking
  31. All animations should run on the composition thread  - independent of UI

    Slide 31 - All animations should run on the composition thread - independent of UI

    • Animating our UI
    • ThemeTransitions
    • Easy
    • Implicit
    • Storyboards
    • Fully customizable
    • Verbose
    • Limited customization
    • Difficult to make consistent
    • Require Custom Triggers
  32. Animation panel demo

    Slide 32 - Animation panel demo

  33. Flexibility and power of storyboards

    Slide 33 - Flexibility and power of storyboards

    • Our animations can use any timing curve.
    • Multiple KeyFrames.
    • Uses Office’s existing animation definitions
    • Office defines a set of animation types as an AnimationClass.
    • Animation definitions can then be shared across platforms.
    • Animations triggered on reposition, show and hide
    • Integrating animations into a custom panel
    • Office Panel creates implicit, fluid, flexible and interruptible animations.
  34. Developers can customize animations through custom and attached properties

    Slide 34 - Developers can customize animations through custom and attached properties

    • The animation is determined by the AnimationClass property on the panel.
    • Or from an AnimationClassOverride attached property on the specific element.
    • Our Panel implements MeasureOverride and ArrangeOverride
    • Dynamically generates storyboards during arrange
    • Implicit animations
    • Triggering animation automatically makes creating fluid UI easier
  35. child.Arrange(newPos);

    Slide 35 - child.Arrange(newPos);

    • Storyboard s = new Storyboard();
    • DoubleAnimation daX = new DoubleAnimation() { From = oldPos.X – newPos.X, To = 0 };
    • DoubleAnimation daY = new DoubleAnimation() { From = oldPos.Y – newPos.Y, To = 0 };
    • Storyboard.SetTarget(daX, child.RenderTransform);
    • Storyboard.SetTarget(daY, child.RenderTransform);
    • Storyboard.SetTargetProperty(daX, "X");
    • Storyboard.SetTargetProperty(daY, "Y");
    • s.Children.Add(daX);
    • s.Children.Add(daY);
    • s.Begin();
    • What happens if the position changes while an animation is in progress?
    • Animating from old position to new
  36. Positioning content entirely with RenderTransform

    Slide 36 - Positioning content entirely with RenderTransform

    • child.Arrange({0, 0}, finalSize);
    • Storyboard s = new Storyboard();
    • DoubleAnimation daX = new DoubleAnimation() { To = newPos.X };
    • DoubleAnimation daY = new DoubleAnimation() { To = newPos.Y };
    • Storyboard.SetTarget(daX, child.RenderTransform);
    • Storyboard.SetTarget(daY, child.RenderTransform);
    • Storyboard.SetTargetProperty(daX, "X");
    • Storyboard.SetTargetProperty(daY, "Y");
    • s.Children.Add(daX);
    • s.Children.Add(daY);
    • s.Begin();
    • Accounting for interruptions
    • No From Specified
    • Always arrange at 0,0
  37. Normally resize doesn’t animate in XAML

    Slide 37 - Normally resize doesn’t animate in XAML

    • To animate resize you have to turn on UseDependantAnimations.
    • Could use ScaleTransform but that stretches the content.
    • Our solution: split content into multiple layers
    • All our items have been arranged with RenderTransforms.
    • Use ScaleTransform on backgrounds and borders.
    • Allow content to animate to new layout.
    • Triggered during arrange in response to layout changes.
    • Resize animations
  38. Slide 38

    • Word, Excel, PowerPoint, OneNote and the new Mail and Calendar apps are shipping soon.
    • They are built on the public platform.
    • Still work to do but they are looking great.
    • The Win10 platform improvements will make them even better!
    • We are working on integrating new platform features right now.
    • We invented our own databinding replacement…
    • But if x:Bind had existed we wouldn’t have felt the need.
    • Universal Office applications today
  39. One package for mobile and desktop.

    Slide 39 - One package for mobile and desktop.

    • Adapt to changes on the fly.
    • Use consistent crossover points.
    • Layer things appropriately.
    • Keep child elements self-contained.
    • The switch often just involves laying them out differently.
    • Build external communication around what you want it to do, not how it is set up.
    • They are truly universal apps
  40. This code is not based on a fork.

    Slide 40 - This code is not based on a fork.

    • It is the same tree that produces Win32 Office and our web applications.
    • It now also includes the Android tablet versions of Word, Excel and PowerPoint.
    • Universal is built out of our main tree
  41. Universal is built from

    Slide 41 - Universal is built from

    • 96% shared code (by LoC)
    • including the XAML files and related code-behind.
    • If you exclude the XAML pieces, then Universal is built from:
    • 98.6% shared code.
    • Android is built from
    • 95% shared code (by LoC)
    • including the Java files and related code-behind.
    • If you exclude the Java pieces, then Android is builtfrom:
    • 99.7% shared code.
    • So how much code are we sharing?
  42. XAML Session 635: Data Binding: Boost Your App’s Performance Through New Enhancements to XAML Data Binding

    Slide 42 - XAML Session 635: Data Binding: Boost Your App’s Performance Through New Enhancements to XAML Data Binding

    • XAML Session 689: XAML Performance: Techniques for maximizing Universal App experiences build with XAML
    • Microsoft Office Cross-Platform Architecture - @Scale 2014
    • Call to Action