uno icon indicating copy to clipboard operation
uno copied to clipboard

[Android, iOS] Control templates are applied too early

Open dr1rrb opened this issue 7 years ago • 6 comments

I'm submitting a...

  • Bug report (I searched for similar issues and did not find one)

Current behavior

If we instantiate a control and set the Template property, then this template is applied immediately (which leads to invoke the OnApplyTemplate in the control).

Expected behavior

On Windows the template of a control is being applied only when this control is in the visual tree and either we explicitly invoke the ApplyTemplate method, or we wait for the first measure pass.

Note: To get the full behavior of windows, we should be able to do:

var myControl = new MyControl { Template = _myControlTemplate };
_panelInTheVisualTree.Children.Add(myControl); // Template was not applied yet
myControl.ApplyTemplate(); // Will invoke `OnApplyTemplate` synchronously and returns `true`
_panelInTheVisualTree.Children.Remove(myControl); // `myControl` was not measured

But if the panel is not in the visual tree, myControl.ApplyTemplate() should not do anything and returns false

Minimal reproduction of the problem with instructions

var myControl = new MyControl { Template = _myControlTemplate };

Environment

Nuget Package: Uno.UI
Package Version(s): 1.25.0-dev.42

Affected platform(s):
- [x] iOS
- [x] Android
- [?] WebAssembly
- [ ] Windows
- [ ] Build tasks

Visual Studio : _Irrelevant_
Relevant plugins: _Irrelevant_

dr1rrb avatar Sep 12 '18 14:09 dr1rrb

This got mitigated by #192, but it's still not properly aligned with UWP.

dr1rrb avatar Sep 12 '18 20:09 dr1rrb

ApplyTemplate() doesn't require the view to be in the visual tree, it just requires Template to be non-null. If the Control has an implicit style then its Template will be null on UWP until it's in the visual tree because the Style can't be resolved until that point. The root cause then is #119.

For now the best workaround is to set FeatureConfiguration.Control.UseLegacyLazyApplyTemplate = true.

davidjohnoliver avatar Sep 27 '18 01:09 davidjohnoliver

The specific issue we're encountering involves a custom control that wraps a ListView and accepts a DataTemplateSelector as a wrapper but includes a default DataTemplateSelector. By the time we have received the DataTemplateSelector the ListView has already been rendered using the default DataTemplateSelector.

peternary avatar Aug 06 '19 16:08 peternary

This is causing some troubles again with this:

<Setter Property="DisplayTemplate" Value="{StaticResource templTextDisplay}" />
<Setter Property="InputTemplate" Value="{StaticResource templTextInput}" />

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate>
            <Rectangle Fill="Red" Stretch="Fill" />
        </ControlTemplate>
    </Setter.Value>
</Setter>

If in the callback of the DisplayTemplateProperty you do something like Template = DisplayTemplate, then the OnApplyTemplate will be invoked twice (once with the DisplayTemplate and a second time withe the template defined in the style for the Template property).

On Windows the template is applied only on first measure, so the OnApplyTemplate is invoked only once (with the DisplayTemplate, but this is certainly due to https://github.com/unoplatform/uno/issues/3398)

dr1rrb avatar Jun 19 '20 19:06 dr1rrb

This was causing an issue in one of the tests that I worked around in #14368.

For my case though, the issue is that control templates are not applied on the first measure pass, not that they are applied early.

I added some code comments in #14368 that mentions some of the relevant parts of WinUI source code.

Youssef1313 avatar Nov 09 '23 13:11 Youssef1313

This will be easily fixable after https://github.com/unoplatform/uno/pull/18261/ is merged

Youssef1313 avatar Oct 06 '24 07:10 Youssef1313

This is only relevant to native renderer, closing. CC @Jen-Uno

MartinZikmund avatar Jul 15 '25 13:07 MartinZikmund

@MartinZikmund I'm curious. Are native renderers removed completely? Or they are there but are no longer a supported scenario and exists only for backcompat?

Youssef1313 avatar Jul 15 '25 13:07 Youssef1313