0

WinUI 3 c++/winrt. The DataTemplate is listed at the top of the page:

<Page.Resources>
    <DataTemplate x:Key="SomeViewTemplate" x:DataType="local:SomeModel">
        <StackPanel>
            <TextBlock Text="{x:Bind val1}"/>
            <RatingControl MaxRating="{x:Bind val2}" />
        </StackPanel>
    </DataTemplate>
</Page.Resources>

Everything works fine on this page. How can I make this DataTemplate usable on other pages? In what place (file) should it be placed?

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • As [Lookup behavior for XAML resource references](https://learn.microsoft.com/en-us/windows/apps/design/style/xaml-resource-dictionary#lookup-behavior-for-xaml-resource-references) said, *If the requested resource is not found in the immediate resources, the next lookup step is to check the Application.Resources property. **Application.Resources** is the best place to put any app-specific resources that are referenced by multiple pages in your app's navigation structure.* @breadman any update? – YangXiaoPo-MSFT Jul 10 '23 at 06:23
  • @YangXiaoPo-MSFT If I put DataTemplate (as in question) in App.xaml in in I get error "WMC9999 ImplementsIObservableVector: XamlType does not have metadata" If you put it in other places in this file - it also does not work. That other proposed solution also does not work as it should. – breadman Jul 10 '23 at 15:04

2 Answers2

2

Let's say you have your DataTemplate in a ResourceDictionary "DataTemplates.xaml". Note that you need to use Binding instead of x:Bind.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DataTemplateExample">

     <DataTemplate x:Key="SomeViewTemplate">
         <StackPanel>
             <TextBlock Text="{Binding val1}"/>
             <RatingControl MaxRating="{Binding val2}" />
         </StackPanel>
     </DataTemplate>

</ResourceDictionary>

Add it to App.xaml,

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
            <!--  Other merged dictionaries here  -->
            <ResourceDictionary Source="DataTemplates.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!--  Other app resources here  -->
    </ResourceDictionary>
</Application.Resources>

Then you should be able to use it.

<ListView
    ItemTemplate="{StaticResource SomeViewTemplate}"
    ItemsSource="{x:Bind Items, Mode=OneWay}" />
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • I want to add items to GridView in this way: ` ` Everything worked fine before, but now all elements (val1, val2) are empty: Text = "", MaxRating by default 5. – breadman Jul 10 '23 at 13:46
  • By the way, in c#, this xaml code works as it should. Perhaps the problem is in the implementation of the SomeModel class in c++. But then why did everything work when the template was specified at the beginning of the page (template as in the question). – breadman Jul 10 '23 at 15:24
  • I cannot reproduce. You can refer to [XAML controls; bind to a C++/WinRT property](https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/binding-property) and [XAML items controls; bind to a C++/WinRT collection](https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/binding-collection) for c++. – YangXiaoPo-MSFT Jul 11 '23 at 06:27
  • @YangXiaoPo-MSFT “I cannot reproduce” - You cannot reproduce behavior that I described? That is, did you manage to create a DataGrid, as in my comment above, using a DataTemplate that can be used in all pages (files) in c++? If you mean this, it would be sooooooo grateful if you share the complete application code in which this simple functionality is implemented. – breadman Jul 11 '23 at 15:20
0

When I placed DataTemplate in App.xaml or a separate ResourceDictionary as @AndrewKeepCoding answered, a Xaml Compiler error at x:DataType, XamlCompiler error WMC0612: The XAML Binary Format (XBF) generator reported syntax error '0x09C4' : Property Not Found, was raised. However, It's necessary to specify x:DataType in order to make the DataTemplate take effect.

So, my conclusion is DataTemplate cannot be global in c++ and DataTemplate also states limited properties to use.

Binding to a C++/WinRT collection costs me a long time until I find PhotoEditor sample. Must specify IInspectable instead of a custom runtime class name.

enter image description here

import "BookSku.idl";

namespace App1
{
    [default_interface]
    runtimeclass MainWindow : Microsoft.UI.Xaml.Window
    {
        MainWindow();
        Int32 MyProperty;
        Windows.Foundation.Collections.IVector<IInspectable> BookSkus{ get; };
    }
}

enter image description here

Update:

According to Resource dictionaries with {x:Bind}, It's possible to use x:Bind and x:DataType in Resource dictionaries. That's why it works in c#. But there is no document about how to implement it in cppwinrt. A related thread: https://stackoverflow.com/a/98422/15511041

YangXiaoPo-MSFT
  • 1,589
  • 1
  • 4
  • 22
  • @breadman I have updated my answer about [why it works in c#](https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth#resource-dictionaries-with-xbind). – YangXiaoPo-MSFT Jul 14 '23 at 06:05