XAML controls; bind to a C++/WinRT property

什么是可观测的属格?如果runtimeclass BookSku有一个属格叫做Title。如果在Title发生改变的时候会产生 INotifyPropertyChanged::PropertyChanged 事件,那么Title就是一个可观测的属格。

任何runtimeclass,只要是从某个runtimeclass继承出来的,叫做composable class,有额外的限制。composable class的基类必须是windows自带的一个类。比如说,可以从Windows.UI.Xaml.DependencyObject继承。

由于没有反射,C++/WinRT中用到XAML的属性需要在IDL中声明,XAML编译器通过winmd来获取反射。这也算是一种折衷的办法。如果 {x:Bind} 的目标是XAML元素的话,要在IDL中声明该目标。

当{x:band}绑定到布尔值时,会显示Windows.Foundation.IReference,而不是true和false。

XAML items controls; bind to a C++/WinRT collection

和侦听单个权属相比,侦听一个集合的改动,需要通过IObservableVector<T>::VectorChanged事件

XAML custom (templated) controls with C++/WinRT

试验过程中犯了一个错误,导致不成功。Generic.xaml必须放在Themes目录。Themes后面带有s,如果敲错了少了s,XAML就找不到这个Generic.xaml了。会遇到类似 Is this properly supported in XAML Designer? #1440 的问题问题。

参考 WPF: What’s the difference between App.xaml and Generic.xaml?

App.xaml is a XAML part of the Application class - the single centralized place where you define application-wide logic and resources. While Generic.xaml, being located in the Themes directory of your project, is a dictionary where you define default styles for all your custom controls. This dictionary is used when there is no windows theme-specific dictionary in the Themes folder. For example, you might have the following structure of the Themes directory:

MyProject
   - Themes
     - Generic.xaml // Default styles if current theme is non of the themes below
     - Classic.xaml // Styles for “Classic” Windows 9x/2000 look on Windows XP.
     - Luna.NormalColor.xaml // Styles for default blue theme on Windows XP.
     - Luna.Homestead.xaml //  Styles for olive theme on Windows XP.
     - Luna.Metallic.xaml // Styles for silver theme on Windows XP.
     - Royale.NormalColor.xaml // Styles for default theme on Windows XP Media Center Edition.
     - Aero.NormalColor.xaml // Styles for default theme on Windows Vista

更多参考What is so special about Generic.xaml?

另外,如何在XAML中重定义方法,并不是通过虚函数,而是直接定义普通方法:Implementing overridable functions, such as MeasureOverride and OnApplyTemplate

Boxing and unboxing scalar values to IInspectable with C++/WinRT

C++/WinRT的winrt::box_value、 winrt::unbox_value、winrt::unbox_value_or 可以把标量(Scalar)装箱和拆箱到WinRT的基本接口IInspectable中。

比如说 winrt::hstring是一个标量,可以使用winrt::box_value将其装箱。下面是另外一个例子:

Button().Content(winrt::box_value(L"Clicked"));

拆箱的例子:

void Unbox(winrt::Windows::Foundation::IInspectable const& object)
{
    hstring hstringValue = unbox_value<hstring>(object); // Throws if object is not a boxed string.
    hstringValue = unbox_value_or<hstring>(object, L"Default"); // Returns L"Default" if object is not a boxed string.
    float floatValue = unbox_value_or<float>(object, 0.f); // Returns 0.0 if object is not a boxed float.
}

如果你想检查装箱后的值的类型也是可以的,

float pi = 3.14f;
auto piInspectable = winrt::box_value(pi);
auto piPropertyValue = piInspectable.as<winrt::Windows::Foundation::IPropertyValue>();
WINRT_ASSERT(piPropertyValue.Type() == winrt::Windows::Foundation::PropertyType::Single);

将值转为IPropertyValue类型,并调用其Type()方法。

WINRT_ASSERT宏会扩展为 _ASSERTE.

Error handling with C++/WinRT

WinRT ABI级别是通过HRESULT这个返回值来返回错误的,而不是通过异常。在C++/WinRT生成的代码中,会通过to_result()将异常转化为HRESULT,来阻止异常扩散,并返回相应的错误值。to_result()能处理的异常包括std::exception或者winrt::hresult_error 派生出来的异常。对于从winrt::hresult_error 派生出来的异常,HRESULT返回值能够提供更多信息;对于std::exception派生出来的异常,一般返回E_FAIL。

[[MS-ERREF]: Windows Error Codes]: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/1bc92ddf-b79e-413c-bbaa-99a5281a6c90

A simple C++/WinRT Windows UI Library example

Windows UI Library 提供了一套向后兼容的XAML UI库。如何使用,可以查看 https://docs.microsoft.com/en-us/uwp/toolkits/winui/getting-started

可以把WinUI的头文件加入到pch.h中:

// pch.h
...
#include "winrt/Microsoft.UI.Xaml.Automation.Peers.h"
#include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h"
#include "winrt/Microsoft.UI.Xaml.Media.h"
#include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h"

WinUI增加了以下以Microsoft开头(而不是以Windows开头)的命名空间:

  • Microsoft.UI.Xaml
  • Microsoft.UI.Xaml.Automation.Peers
  • Microsoft.Ui.Xaml.Controls
  • Microsoft.UI.Xaml.Controls.Primitives
  • Microsoft.UI.Xaml.CustomAttributes
  • Microsoft.UI.Xaml.Media
  • Microsoft.Ui.Xaml.XamlTypeInfo

WinUI的最近版本:

其中2.2版本添加了tabview

WinUI 3.0 roadmap - we need your input! #717

(本篇完)

2020-11-14更新

在资源字典中引用其他XAML,可以使用ms-appx:

         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ms-appx:///Themes/Nighttime.xaml" />
         </ResourceDictionary.MergedDictionaries>

或者直接使用路径:

         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Themes/Nighttime.xaml" />
         </ResourceDictionary.MergedDictionaries>

如果找不到文件,在除了Generic.xaml以外的xaml中会显示错误。