使用XAML和C++/WinRT时,IDL中必须包含哪些属性/函数?

ujv3wf0j  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(122)

我为用C++/WinRT编写的自定义XAML控件编写的IDL中必须包含哪些属性/函数/任何内容?

示例

当我在Visual Studio中创建自定义C++/WinRT XAML控件时,它会创建4个文件:

  • MyControl.xaml
  • MyControl.idl
  • MyControl.h
  • MyControl.cpp

IDL文件是基本的,包含一个简单的属性:

namespace MyNamespace
{
    [default_interface]
    runtimeclass MyControl : Windows.UI.Xaml.Controls.UserControl
    {
        MyControl();
        Int32 MyProperty;
    }
}

有趣的是,除了这个属性之外,.h文件还包括另一个函数:

#pragma once

#include "winrt/Windows.UI.Xaml.h"
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Interop.h"
#include "winrt/Windows.UI.Xaml.Controls.Primitives.h"
#include "MyControl.g.h"

namespace winrt::MyNamespace::implementation
{
    struct MyControl : MyControlT<MyControl>
    {
        MyControl();

        int32_t MyProperty();
        void MyProperty(int32_t value);

        void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    };
}

namespace winrt::MyNamespace::factory_implementation
{
    struct MyControl : MyControlT<MyControl, implementation::MyControl>
    {
    };
}

.xaml绑定到它没有问题:

<!-- ... -->
<Button x:Name="Button" Click="ClickHandler">Click Me</Button>
<!-- ... -->

问题

我不清楚什么时候需要在IDL上引入函数或属性,以便在XAML中使用它。
所有的属性都需要添加到IDL中吗?只是依赖属性吗?函数必须出现在IDL中吗?
为什么MyProperty出现在IDL中,而ClickHandler没有出现?
谢谢你!
Disclaimer: I work for Microsoft.

gev0vcfq

gev0vcfq1#

简短回答:
| | | 需要在IDL中?|需要在C中实现?|
| - -|- -|- -|- -|
| 属性|x:Bind|是的,属性必须在IDL中公开.|是的,你必须实现该属性.|
| | Binding|否,但您的控件必须实现ICustomPropertyProviderICustomProperty。请参见在C
/WinRT中使用{Binding}标记扩展。|(您必须实现这些接口,所以是的)|
| 功能说明|委派|否,函数只需要在您的实现中是公共的。|是的,根据定义,你必须实现你想要调用的函数。|
| | x:Bind|是的,函数必须在IDL中公开.|是的,根据定义,你必须实现你想要调用的函数。|
| 要素|x:Bind|是的,元素必须在IDL中公开.|否,实现代码将自动生成;不要写任何C++。|
或者换一种说法:

  • 使用x:Bind的任何内容都需要在IDL中。
  • 这包括x:Bind的 * 所有 *---属性和函数是显而易见的,但也包括 * 元素 *(请参阅元素到元素绑定)。因此,如果您希望将x:BindTextBlockContentTextBoxText进行绑定,则需要在IDL中公开TextBox
  • 其他所有内容都不需要在IDL中。
  • 若要使用旧式的(效率较低且较脆弱)Binding,您的控件必须实作ICustomPropertyProviderICustomProperty。请参阅使用{Binding}标记延伸模块搭配C++/WinRT。
  • 如果您将函式指涉为委派(例如PointerMoved="MyTextBlock_PointerMovedHandler"),则函式只需要是控件类别中的公用方法即可。

MSDN的XAML controls; bind to a C++/WinRT property提供了完整的答案:
使用XAML {x:Bind} markup extension使用的所有实体都必须在IDL中公开。此外,如果XAML标记包含对另一个也在标记中的元素的引用,则该标记的getter必须存在于IDL中。

<Page x:Name="MyPage">
    <StackPanel>
        <CheckBox x:Name="UseCustomColorCheckBox" Content="Use custom color"
             Click="UseCustomColorCheckBox_Click" />
        <Button x:Name="ChangeColorButton" Content="Change color"
            Click="{x:Bind ChangeColorButton_OnClick}"
            IsEnabled="{x:Bind UseCustomColorCheckBox.IsChecked.Value, Mode=OneWay}"/>
    </StackPanel>
</Page>

ChangeColorButton元素通过绑定引用UseCustomColorCheckBox元素。因此,此页的IDL必须声明一个名为UseCustomColorCheckBox的只读属性,以便绑定可以访问它。
UseCustomColorCheckBox的单击事件处理程序委托使用经典的XAML委托语法,因此不需要IDL中的条目;它只需要在实现类中是公共的。2另一方面,ChangeColorButton也有一个{x:Bind}单击事件处理程序,它也必须进入IDL。

runtimeclass MyPage : Windows.UI.Xaml.Controls.Page
{
    MyPage();

    // These members are consumed by binding.
    void ChangeColorButton_OnClick();
    Windows.UI.Xaml.Controls.CheckBox UseCustomColorCheckBox{ get; };
}

您不需要提供UseCustomColorCheckBox属性的实作。XAML程式码产生器会为您提供实作。

相关问题