Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinUI 3 DataTemplateSelector always crashed when using AOT

// English is not my native language; please excuse typing errors.

WinUi3 dotNet8.0 Win11(22631.4317) VisualStudio Enterprise 2022 17.14.0


First, I use a DataTemplateSelector in a ListView

<ListView ItemTemplateSelector="{StaticResource ContextItemTemplateSelector}"/>

Here is an example. Remember to enable AOT.

I put an example on github if you need,thank you.

// Some useless details are removed
public interface A{}
public class B:A{}
public class C:A{}
public class ADataTemplateSelector : DataTemplateSelector
{
    public DataTemplate TemplateForB { get; set; }
    public DataTemplate TemplateForC { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        if (item is B)
            return TemplateForB;
        else if (item is C)
            return TemplateForC;
        
        return base.SelectTemplateCore(item);
    }
}
<Page>
<Page.Resources>
    <!-- Some useless details are removed-->
    <DataTemplate x:Key="BTemplate" x:DataType="local:B"/>
    <DataTemplate x:Key="CTemplate" x:DataType="local:C"/>
    <local:ADataTemplateSelector x:Key="ATemplateSelector"
                                TemplateForB="{StaticResource BTemplate}"
                                TemplateForC="{StaticResource CTemplate}" />
</Page.Resources>
<ListView ItemsSource="{x:Bind Items, Mode=OneWay}" 
          ItemTemplateSelector="{StaticResource ATemplateSelector}" />
</Page>

Then, it crashes with a unhandled exception,like:

Specified cast is not valid.
   WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr)
    ABI.Microsoft.UI.Xaml.IFrameworkElementOverridesMethods.MeasureOverride(IObjectReference _obj, Size availableSize)
   Microsoft.UI.Xaml.FrameworkElement.MeasureOverride(Size availableSize) Microsoft.UI.Xaml.FrameworkElement.Microsoft.UI.Xaml.IFrameworkElementOverrides.MeasureOverride(Size availableSize)
   ABI.Microsoft.UI.Xaml.IFrameworkElementOverrides.Do_Abi_MeasureOverride_0(IntPtr thisPtr, Size availableSize, Size* result)

Then, I disabled Aot, and everything ran correctly. (PublishTrimmed seemed ok)


(an old story between me and aot)

It once crashed when setting the ListView.ItemSources (only when aot is enabled)

I managed to fix it by

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

And this code now still lies in the project.


I disabled Aot and it worked well. Probably it's another problem of aot.


I found nothing referring to both DataTemplateSelector and AOT.


What I expect is only that it would work correctly just like when aot is disabled.

like image 973
Lan Avatar asked Nov 14 '25 15:11

Lan


1 Answers

Your project doesn't even work w/o AOT publishing, it raises an InvalidCastException error:

InvalidCastException

The problem comes from the fact you want to expose a "pure" managed object (of type ADataTemplateSelector) to the underlying WinUI3 (native) layers but there's not enough information for C#/WinRT to project this type back. Invalid cast here means: this type doesn't implement what's needed to participate to the XAML/WinUI3 party.

If you work with Visual Studio and take a closer look over this managed class, you will see this:

partial warning

Class ... implements WinRT interface but it ... isn't marked partial.

The warning tells you to add a partial keyword to the class to allow C#/WinRT to generate necessary information for this type to be recognised as a valid WinUI3 framework type:

public partial class ADataTemplateSelector : DataTemplateSelector
{
    ...
}

Once you've done that the warning should go and the project should run and work when published as AOT.

PS: there are other warnings in this code. In general and especially with AOT publishing you really want to make sure there are none left, even when it seems to work:

AOT warnings

like image 197
Simon Mourier Avatar answered Nov 17 '25 09:11

Simon Mourier