XamlReader не удается проанализировать DataTemplate с помощью свойства типа данных

#uwp #winrt-xaml #uwp-xaml #c -winrt

#uwp #winrt-xaml #uwp-xaml #c -winrt

Вопрос:

Я пытаюсь создать DataTemplate для ListView динамически с помощью cpp / winrt:

 auto template_src = R"(
    <DataTemplate 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MyNamespace"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        x:DataType="local:MyListItem"
    >
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{x:Bind MyProperty}" HorizontalAlignment="Left"/>
        </StackPanel>
    </DataTemplate>
)";
auto tmpl = winrt::Windows::UI::Xaml::Markup::XamlReader::Load(winrt::to_hstring(template_src)).as<winrt::Windows::UI::Xaml::DataTemplate>();
  

При вызове Load генерируется исключение:

Свойство ‘DataType’ не было найдено в типе ‘DataTemplate’. [Строка: 8 Позиция: 17]

Тип MyListItem является пользовательским типом winrt. Это DataType свойство требуется при использовании x:Bind . Если я удалю свойство и заменю привязку, как показано ниже, это не приведет к сбою, но и не отобразит:

 auto template_src = R"(
    <DataTemplate 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MyNamespace"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
    >
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding MyProperty}" HorizontalAlignment="Left"/>
        </StackPanel>
    </DataTemplate>
)";
auto tmpl = winrt::Windows::UI::Xaml::Markup::XamlReader::Load(winrt::to_hstring(template_src)).as<winrt::Windows::UI::Xaml::DataTemplate>();
  

Если я объявлю шаблон в Xaml:

 <Page.Resources>
    <DataTemplate x:Key="ListTemplate" x:DataType="local:MyListItem">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{x:Bind MyProperty, Mode=OneWay}" HorizontalAlignment="Left"/>
        </StackPanel>
    </DataTemplate>
</Page.Resources>
  

и загрузите его

 Resources().Lookup(winrt::box_value(L"ListTemplate")).as<winrt::Windows::UI::Xaml::DataTemplate>());
  

список отображается правильно.

Ответ №1:

Свойство ‘DataType’ не было найдено в типе ‘DataTemplate’. [Строка: 8 Позиция: 17]

Основываясь на документе, в нем упоминается, что мы не можем создавать привязки {x:Bind} в коде, поэтому использование {x:Bind} в коде о template_src вызывает исключение. Вы можете использовать {Binding} для замены {x:Bind} .

Если я удалю свойство и заменю привязку, как показано ниже, это не приведет к сбою, но и не отобразит:

Если вы используете расширение {Binding} в C / WinRT, вам следует добавить атрибут BindableAttribute к любому классу среды выполнения, с которым вы хотите использовать расширение разметки {Binding}. Для получения более подробной информации об этом вы можете обратиться к этому документу . В этом случае вам необходимо добавить [bindable] в ваш idl-файл, чтобы использовать привязку. Например:

Model.idl:

 [bindable]
runtimeclass BookSku : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
    String Title;
}
  

Чтобы отобразить список, пожалуйста, проверьте следующий код:

Page.cpp

 auto template_src = R"(
    <DataTemplate 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:MyNamespace"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    >
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Title}" HorizontalAlignment="Left"/>
        </StackPanel>
    </DataTemplate>
)";
hstring str = winrt::to_hstring(template_src);
auto tmpl = winrt::Windows::UI::Xaml::Markup::XamlReader::Load(str);

myListView().ItemsSource(MyListItem());
myListView().ItemTemplate(tmpl.try_as<DataTemplate>());