Home > Software design >  What properties/functions have to go in an IDL when using XAML and C /WinRT?
What properties/functions have to go in an IDL when using XAML and C /WinRT?

Time:09-17

What properties/functions/anything must go in the IDLs that I write for custom XAML controls written in C /WinRT?

Example

When I create a custom C /WinRT XAML control in Visual Studio, it creates 4 files:

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

The IDL file is basic and includes a simple property:

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

Interestingly, the .h file also includes another function in addition to this property:

#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>
    {
    };
}

Which the .xaml has no problem binding to:

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

Question

It's not clear to me when I need to introduce a function or property on my IDL in order to consume it in XAML.

Do all properties need to be added to the IDL? Just dependency properties? Do functions ever have to appear in the IDL?

Why does MyProperty appear in the IDL, but not ClickHandler?

Thanks!

CodePudding user response:

Short answer:

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 .

Or another way of putting it:

  • Anything using x:Bind needs to be in the IDL.

    • This includes everything with x:Bind---properties and functions are obvious, but also elements (see Element-to-element binding). So if you want to x:Bind the Content of a TextBlock to the Text of a TextBox, you'll need to expose the TextBox in the IDL.
  • Everything else does not need to be in the IDL.


MSDN's XAML controls; bind to a C /WinRT property provides the full answer:

All entities consumed by using the XAML {x:Bind} markup extension must be exposed publicly in IDL. Furthermore, if XAML markup contains a reference to another element that's also in markup, then the getter for that markup must be present in 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>

The ChangeColorButton element refers to the UseCustomColorCheckBox element via binding. So the IDL for this page must declare a read-only property named UseCustomColorCheckBox in order for it to be accessible to binding.

The click event handler delegate for UseCustomColorCheckBox uses classic XAML delegate syntax, so that doesn't need an entry in the IDL; it just needs to be public in your implementation class. On the other hand, ChangeColorButton also has an {x:Bind} click event handler, which must also go into the 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; };
}

You don't need to provide an implementation for the UseCustomColorCheckBox property. The XAML code generator does that for you.

  • Related