Как создать пользовательский элемент управления XAML в коде? - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь реализовать пользовательский элемент управления XAML в коде, используя C ++ / WinRT.Моя попытка реализации, однако, не удалось скомпилировать.В качестве подтверждения концепции я использовал этот код:

#pragma once

#include <winrt/Windows.UI.Xaml.Controls.h>

namespace MyApp
{
    struct MyControl : winrt::implements<MyControl, winrt::Windows::UI::Xaml::Controls::Control>
    {
    };
}

Это привело к следующей ошибке компилятора:

1>MyControl.cpp
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(6416): error C2079: 'winrt::impl::producer<D,winrt::Windows::UI::Xaml::Controls::Control,void>::vtable' uses undefined struct 'winrt::impl::produce<D,I>'
1>        with
1>        [
1>            D=MyApp::MyControl
1>        ]
1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\cppwinrt\winrt\base.h(7163): note: see reference to class template instantiation 'winrt::impl::producer<D,winrt::Windows::UI::Xaml::Controls::Control,void>' being compiled
1>        with
1>        [
1>            D=MyApp::MyControl
1>        ]
1>c:\xxx\mycontrol.h(8): note: see reference to class template instantiation 'winrt::implements<MyApp::MyControl,winrt::Windows::UI::Xaml::Controls::Control>' being compiled

Я не могу понять компиляторошибка.По-видимому, вы не можете реализовать элемент управления XAML так же, как и другие типы для использования средой выполнения Windows.

Что требуется для реализации пользовательского элемента управления XAML в коде?

1 Ответ

0 голосов
/ 13 июня 2018

«Наследование» или «наследование» в WinRT незначительно отличается от наследования C ++.Поскольку это COM-интерфейсы, когда вы создаете подкласс WinRT-класса времени исполнения, вы действительно COM-агрегирование в сочетании с реализацией переопределяемых интерфейсов базового типа .Из-за аспекта агрегации COM это значительно сложнее, чем стандартное наследование C ++, что со всеми делегированием / неделегатированием, специальной конструкцией и т. Д. Это было бы серьезной проблемой в WRL, но C ++ / CX провела кучу волшебства компилятора подкапюшон, чтобы абстрагироваться от этого.К счастью, C ++ / WinRT помогает вам с предоставлением двух типов абстракций, не прибегая к невидимой магии.

Если вы создаете тип, который не должен быть видимым извне (например, приложение, в отличие откомпоненту времени выполнения) C ++ / WinRT предоставляет удобные помощники для этого:

#pragma once

#include <winrt/Windows.UI.Xaml.Controls.h>

namespace MyApp
{
    struct MyControl : winrt::Windows::UI::Xaml::Controls::ControlT<MyControl>
    {
        void OnTapped(winrt::Windows::UI::Xaml::Input::TappedRoutedEventArgs const&);
    };
}

Этот базовый тип ControlT будет правильно создавать агрегированный базовый экземпляр Control и делегировать ему базовые методы, а также реализовывать«переопределенные» интерфейсы.Все эти переопределяемые методы получают реализацию-заполнитель, в которой по умолчанию вызывается базовый метод, но вы можете переопределить их самостоятельно и получить собственное поведение.

Если, с другой стороны, вам необходимо создать проектируемый типчерез IDL:

namespace MyApp
{
  [default_interface]
  runtimeclass MyControl : Windows.UI.Xaml.Controls.Control
  {
    MyControl();
  };
}

Это будет генерировать леса, аналогичные встроенному в ControlT случае выше, но также проецирует ваш тип.Фактически, если вы изучите сгенерированный файл для этого типа (в этом примере, MyControl.gh), вы увидите MyControlT, где все это подключается.

(Примечание: [default_interface]Атрибут необходим только в том случае, если у вас есть пустой, конструируемый, запечатанный класс времени выполнения. После того, как вы добавите члены, midl будет синтезировать интерфейс по умолчанию без каких-либо других действий.

...