【问题标题】:What properties/functions have to go in an IDL when using XAML and C++/WinRT?使用 XAML 和 C++/WinRT 时,IDL 中必须包含哪些属性/函数?
【发布时间】:2021-09-09 23:30:36
【问题描述】:

我为用 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

谢谢!

【问题讨论】:

标签: xaml winrt-xaml c++-winrt


【解决方案1】:

简答:

Needs to be in IDL? Needs to be implemented in C++?
Property x:Bind ✅ Yes, the property must be exposed in the IDL. ✅ Yes, you must implement the property.
Binding ❌ No, but your control must implement ICustomPropertyProvider and ICustomProperty. See Using the {Binding} markup extension with C++/WinRT. (You must implement those interfaces, so yes)
Function Delegate ❌ No, the function simply needs to be public in your implementation. ✅ Yes, by definition you must implement the function you want to call.
x:Bind ✅ Yes, the function must be exposed in the IDL. ✅ Yes, by definition you must implement the function you want to call.
Element x:Bind ✅ Yes, the element must be exposed in the IDL. ❌ No, the implementation code will be auto-generated; don't write any C++.

或者换一种说法:

  • 使用 x:Bind 的任何内容都需要在 IDL 中。

    • 这包括everythingx:Bind---属性和功能很明显,还有元素(见Element-to-element binding)。因此,如果您想将x:BindTextBlockContent 转换为TextBoxText,则需要在IDL 中公开TextBox
  • 其他所有内容都不需要在 IDL 中。


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 中的条目;它只需要在您的实现类中公开。另一方面,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 代码生成器会为您完成这项工作。

【讨论】:

  • 很好的答案!你可以mark你的被接受,这样它可以帮助其他有同样问题的人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-29
  • 2017-12-04
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
相关资源
最近更新 更多