Как использовать атрибут TemplatePart в пользовательском элементе управления?

Я начал разработку пользовательского элемента управления UWP XAML с использованием новой языковой проекции C++/WinRT. Я правильно понял базовую структуру, но я застрял, когда дело доходит до определения атрибута TemplatePartAttribute. В C# и даже в C++/CX это довольно просто, потому что язык имеет прямую поддержку для этого.

Теперь в C++/WinRT я предполагаю, что мне нужно определить атрибут runtimeclass в исходном коде MIDL, но я понятия не имею, как это сделать правильно. Например:

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

    /* … */
}

В то время как свойство Name для TemplatePartAttribute легко установить, потому что это String, как мне установить свойство Type - три ??? - (что означает TypeName в среде выполнения Windows)? Я не нашел никакой документации по этому поводу ни в официальных документах C++/WinRT, ни в документах MIDL 3.0.

РЕДАКТИРОВАТЬ (ВРЕМЕННОЕ РЕШЕНИЕ):
Кажется, что атрибут TemplatePart не требуется для использования части шаблона в коде (используя метод GetTemplateChild()), я все равно могу получить ссылку на элемент PART_Button.


person Florian S.    schedule 11.10.2018    source источник
comment
@CoCaIceDew Это бесполезно в отношении заданного вопроса. Во-первых, я не читаю по-китайски (полагаю, да), а во-вторых, речь идет о C#. Моя проблема связана с C++, а точнее с новой языковой проекцией C++/WinRT.   -  person Florian S.    schedule 13.10.2018


Ответы (1)


Вы просто указываете имя типа для второго параметра.

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

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

Что-то вроде этого должно работать.

person Ryan Shepherd    schedule 15.10.2018
comment
Это то, что я попробовал первым, не с отдельным классом среды выполнения, но я указал Windows.UI.Xaml.Controls.Button в атрибуте, используя тот же синтаксис, что и выше (даже в виде строки, подобной первой). Не работает, компилятор MIDL выдает ошибку. Ваше решение (с использованием отдельного класса среды выполнения) также не работает, особенно когда речь идет о запечатанных элементах управления (например, Button нет, а CaptureElement). - person Florian S.; 16.10.2018
comment
Какую ошибку MIDL вы сталкиваетесь? Я подозреваю, что это тот, который говорит, что типизированный атрибут должен находиться в том же пространстве имен, что и связанный с ним тип. Вот почему вы столкнетесь с ошибкой, если попытаетесь предоставить атрибуту TemplatePart что-то вроде Windows.UI.Xaml.Controls.Button - это пространство имен Windows.UI.Xaml.Controls, которое не находится в том же пространстве имен, что и ваш элемент управления. - person Ryan Shepherd; 17.10.2018
comment
У меня сейчас нет доступа к проекту, я посмотрю позже, но я совершенно уверен, что это не та ошибка, которую вы упомянули. Я думаю, что это было связано с синтаксисом (ошибка парсера). - person Florian S.; 18.10.2018
comment
@RyanShepherd, почему это ограничение действует для MIDL? Код C# UWP может без проблем использовать [TemplatePart("MyTemplate", typeof(Windows.UI.Xaml.Controls.Button))] - person Charles Milette; 08.07.2021
comment
@Charles Milette это раньше меня, но я предполагаю, что это потому, что правила для представления System.Type в пользовательских атрибутах диктуют полное каноническое имя, если тип, на который ссылаются, не находится в текущей сборке (или mscorlib), которая включает версию, культуру и общедоступность жетон ключа. Эта информация (предположительно) легко доступна в компиляторах C# (и, возможно, C++/CX), но не в текстовом файле MIDL, importв другом MIDL. Сегодня MIDL может напрямую импортировать winmd, так что я полагаю, что это может быть теоретически осуществимо, но нетривиально и вряд ли будет запланировано без большого спроса. - person Ryan Shepherd; 10.07.2021