Ismael_aheartful
Topic Author
Posts: 2
Joined: 16 Aug 2021, 15:22

VisualTreeHelper on Unity not working properly

04 Nov 2021, 19:50

I've been implementing a custom control for our game's UI on Unity, to scale elements based on differences from a reference resolution, like the example found in the showcase viewtopic.php?f=12&t=834

I've managed to make it work outside of Unity, adapting some bits and pieces from the code as it is a bit outdated, and it works perfectly on it's own standalone WPF project. But I'm having a problem on Unity, the OnPostInit() method is what in the example uses for getting the child and the control's ContentPresenter and manage the scale.
When OnPostInit() is called in Unity, as I read on the documentation, the Xaml and the elements are loaded and initialized, but the call to VisualTreeHelper.GetChild(this, 0) returns null, as the Visual Hierarchy seems to be empty or not yet initialized. Being unable to find the ContentPresenter, the layout is unable to configure. I've tried with other available initialization callbacks, and the first call to the resize callback at initialization, provided by the ContentControl class but with the same result.

Is this not working currently and I followed an outdated example? Is there a better way to implement it?

We are currently using Unity version 2019.4.5f1 and Noesis version 3.0.12, but in the near future we are planning to update our Unity version and use Noesis 3.1, it the version update would help with this.

The code is as follows:

- The OnPostInit method
public void OnPostInit()
		{
			FrameworkElement templateRoot = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;  // <---- This call returns null on Unity
			this.contentPresenter = (ContentPresenter)templateRoot.FindName("ContentPresenter");
			this.contentPresenterScaleTransform = new ScaleTransform(1f, 1f);
			this.contentPresenter.RenderTransform = this.contentPresenterScaleTransform;

			this.Loaded += this.OnLoaded;
			this.Unloaded += this.OnUnloaded;

			this.RefreshViewBoxMargins();
		}
- The Style and Template for the CustomControl
 <Style TargetType="{x:Type local:ScreenAutoViewbox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ScreenAutoViewbox}">
                            <Grid>
                                <ContentPresenter x:Name="ContentPresenter" />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            
            <Style x:Key="DefaultScreenAutoViewboxStyle" TargetType="{x:Type local:ScreenAutoViewbox}"
                BasedOn="{StaticResource {x:Type local:ScreenAutoViewbox}}" />
-And the Xml where it is used
<local:ScreenAutoViewbox Grid.Row="1"  Grid.Column="1" Margin="0,0,0,0" ScaleMult="1" ScreenInfo="{Binding ScreenInfo}" Style="{StaticResource DefaultScreenAutoViewboxStyle}">
            <Grid HorizontalAlignment="Left" Margin="0,0,0,0">
                <Grid.RowDefinitions>
                    ......
                </Grid.RowDefinitions>
                <Label Content="123456" Grid.Row="1" FontFamily="{StaticResource Font_Default}" Margin="0"/>
                    .....
            </Grid>
        </local:ScreenAutoViewbox>
Thank you in advance!

Tags:
 
User avatar
sfernandez
Site Admin
Posts: 2415
Joined: 22 Dec 2011, 19:20

Re: VisualTreeHelper on Unity not working properly

05 Nov 2021, 10:28

Hi, that sample code is a bit old and was using OnPostInit, which is not available in WPF and that we even deprecated in Noesis 3.1 in favor of standard Initialized or Loaded events.

The visual tree of any control gets generated during its Measure pass (which calls ApplyTemplate) . If you need to access an element of the visual tree you should wait until Loaded event is raised to make sure the control was measured and its visual tree created.

Let me know if that fixes your problem.
 
Ismael_aheartful
Topic Author
Posts: 2
Joined: 16 Aug 2021, 15:22

Re: VisualTreeHelper on Unity not working properly

05 Nov 2021, 11:29

It works perfectly! I thought I tried the Loaded event because I saw those events and seemed like the most obvious approach, but I guess OnPostInit was still being called on its own and making a mess on my testing. The VisualTree returns the child value as intended now.

Thank you so much for the help!
 
User avatar
sfernandez
Site Admin
Posts: 2415
Joined: 22 Dec 2011, 19:20

Re: VisualTreeHelper on Unity not working properly

05 Nov 2021, 12:08

Great, marking this as solved.

Who is online

Users browsing this forum: Google [Bot] and 1 guest