2

I started developing a UWP XAML custom control using the new C++/WinRT language projection. I got the basic structure right, but I'm stuck when it comes to defining the TemplatePartAttribute attribute. In C#, and even C++/CX, this is pretty much straightforward because the language has direct support for this.

Now in C++/WinRT, I assume I have to define the attribute on the runtimeclass in the MIDL source, but I have no idea how to get that right. For example:

[Windows.UI.Xaml.TemplatePart(L"PART_Button", ???)]
runtimeclass CustomControl : Windows.UI.Xaml.Controls.Control
{
    CustomControl();

    /* … */
}

While the Name property of the TemplatePartAttribute is easy to set because it's a String, how do I set the Type property - the three ??? - (which is a TypeName in the Windows Runtime)? I didn't find any documentation about this, neither in the official C++/WinRT docs, nor the MIDL 3.0 ones.

EDIT (WORKAROUND):
It seems that the TemplatePart attribute is not required to use the template part in code (using the GetTemplateChild() method), I can get a reference to the element PART_Button anyways.

Florian S.
  • 206
  • 1
  • 5
  • @CoCaIceDew This is not helpful regarding the question asked. First of all, I don't read Chinese (I assume it is), and second this is about C#. My problem is about C++, more specifically the new C++/WinRT language projection. – Florian S. Oct 12 '18 at 22:06

1 Answers1

1

You simply specify the name of the type for the second param.

runtimeclass Button : Windows.UI.Xaml.Controls.Button
{
  /* ... */
}

[Windows.UI.Xaml.TemplatePart("PART_Button", Button)]
runtimeclass Control : Windows.UI.XAML.Controls.Control
{
  /* ... */
}

Something like that should work.

Ryan Shepherd
  • 755
  • 4
  • 11
  • That's what I tried first, not with a separate runtimeclass but I specified `Windows.UI.Xaml.Controls.Button` on the attribute using the same syntax like above (even as a string like the first one). It doesn't work, the MIDL compiler throws an error. Your solution (using a separate runtimeclass) doesn't work either, especially when it comes to controls that are sealed (`Button` is not, but `CaptureElement`, for example). – Florian S. Oct 16 '18 at 19:00
  • Which MIDL error are you hitting? I suspect it's the one that says a typed attribute must be in the same namespace as the associated type. That's why you'd hit an error if you tried to supply the `TemplatePart` attribute with something like `Windows.UI.Xaml.Controls.Button` - it's in the `Windows.UI.Xaml.Controls` namespace, which is not in the same namespace as your control. – Ryan Shepherd Oct 17 '18 at 05:57
  • I don't have access to the project right now, I'll look into it later, but I'm quite sure it's not the error you mention. I think it was something syntax-related (parser error). – Florian S. Oct 18 '18 at 14:31
  • @RyanShepherd why is this restriction in place for MIDL? C# UWP code can use `[TemplatePart("MyTemplate", typeof(Windows.UI.Xaml.Controls.Button))]` without issue – Charles Milette Jul 08 '21 at 06:41
  • @Charles Milette it's before my time, but I speculate that it's because the rules for `System.Type` representation in custom attributes dictate a full canonical name if the referenced type is not in the current assembly (or mscorlib), which includes version, culture, and public key token. This info is (presumably) readily available in C# compilands (and probably C++/CX), but not in a MIDL text file `import`ing other MIDL. Today, MIDL can directly import winmds, so I'd guess this could be theoretically feasible, but nontrivial, and unlikely to be scheduled without lots of demand. – Ryan Shepherd Jul 09 '21 at 22:50