uno icon indicating copy to clipboard operation
uno copied to clipboard

DataTemplateSelector.SelectTemplateCore is passed a different "container" parameter on Desktop vs. WinwodwsAppSDK, Wasm, Android

Open christianfo opened this issue 9 months ago • 0 comments

Current behavior

I have a ContentControl which utilizes a DataTemplateSelector to select one of several templates depending on the type of content (ViewModel) it is bound to. On WindowsAppSKD, Android, and Wasm (and presumably iOS though I have not tested) DataTemplateSelector.SelectTemplateCore is passed the ContentControl as the container. On Desktop, that method is passed the ContentPresenter used by the ContentControl as a container.

Expected behavior

All platforms to behave the same, and the same as WindowsAppSDK.

How to reproduce it (as minimally and precisely as possible)

Minimal repro: UnoApp25.zip

In this app, MainPage contains two instances of MyContentControl with their Content bound to different types of MyViewModels. MyContentControl uses a different template for each MyViewModel type, selected by a DataTemplateSelector. The commentary in DataTemplateSelector.SelectTemplateCore explains the differences in the incoming "container" parameter on different platforms, and shows the necessary platform dependent code:

    protected override DataTemplate? SelectTemplateCore(object item, DependencyObject container)
    {
        if (item != null && item is MyViewModel vm)
        {
#if !DESKTOP
            // On WindowsAppSDK, Wasm or Android, "container" is the ContentControl.
            var cc = container as MyContentControl;
#else
            // On Desktop, "container" is the ContentPresenter of the ContentControl.
            var cc = (container is ContentPresenter cp) ? cp.TemplatedParent as MyContentControl : null;
#endif

            if (cc != null)
            {
                return (DataTemplate)cc.Resources[vm.DataTemplateName];
            }

            Debug.Assert(false, "Unexpected container type in SelectTemplateCore");
        }
        return null;
    }

Workaround

The platform dependent code shows above does the trick. Nonetheless, the different platforms should all behave the same.

Works on UWP/WinUI

None

Environment

No response

NuGet package version(s)

{ "msbuild-sdks": { "Uno.Sdk": "5.2.108" } }

Affected platforms

No response

IDE

Visual Studio 2022

IDE version

17.9.3

Relevant plugins

No response

Anything else we need to know?

Affected platforms: Desktop

christianfo avatar May 06 '24 17:05 christianfo