asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

NineSlice control does not immediately work correctly.

26 Oct 2020, 22:18

I created a nine slice control, but it has odd behavior. When you first start the application, either through Unity's editor or a standalone, the control will not have any brushes applied. However, if you exit out of Unity's play mode and go back in (or load another nine slice control) it will then start to work. In the editor's case, it will work until after the domain (?) is reloaded (usually from compiling).

It is similar to what is shown in the Images documentation, but this only takes an image source and not individual brushes.
<Grid x:Name="Root">
    <Grid.Resources>
        <Style TargetType="Rectangle">
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="IsHitTestVisible" Value="True" />
            <Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" />
        </Style>
        <ImageBrush
            x:Key="TLeft"
            ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ImageSource}"
            ViewboxUnits="Absolute" />
        <ImageBrush
            x:Key="T"
            ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ImageSource}"
            ViewboxUnits="Absolute" />
        ... Repeat
    </Grid.Resources>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding BorderThickness.Left, RelativeSource={RelativeSource TemplatedParent}}" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="{Binding BorderThickness.Right, RelativeSource={RelativeSource TemplatedParent}}" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="{Binding BorderThickness.Top, RelativeSource={RelativeSource TemplatedParent}}" />
        <RowDefinition Height="*" />
        <RowDefinition Height="{Binding BorderThickness.Bottom, RelativeSource={RelativeSource TemplatedParent}}" />
    </Grid.RowDefinitions>
    <Rectangle
        x:Name="TopLeft"
        Grid.Row="0"
        Grid.Column="0"
        Fill="{StaticResource TLeft}" />
    <Rectangle
        x:Name="TopCenter"
        Grid.Row="0"
        Grid.Column="1"
        Fill="{StaticResource T}" />
        ... Repeat
    <Grid
        x:Name="Middle"
        Grid.Row="1"
        Grid.Column="1"
        IsHitTestVisible="True">
        <Rectangle Fill="{StaticResource C}" IsHitTestVisible="True" />
        <ContentPresenter x:Name="MiddleContent" Margin="{TemplateBinding Padding}" />
    </Grid>
</Grid>
It seems that the image source is not applying when the application is started. Only after I recreate a nine slice control (or exit out of play mode and go back in) does it work correctly.

Here is a WPF example that uses the control I made. Not sure why it throws an exception in the designer, but running the control shows it works:
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: NineSlice control does not immediately work correctly.

27 Oct 2020, 12:13

Hi, I've been investigating this issue and it is related to the way we have implemented control templates in Noesis. The problem I'm seeing is that the resources returned by FindResource are not the ones being applied to the Rectangles when template gets instantiated. I created ticket #1822 to follow this issue.

The workaround is to directly access the ImageBrush from each Rectangle.Fill:
_tLeft = (ImageBrush)((Rectangle)Template.FindName("TopLeft", this)).Fill;
 _t = (ImageBrush)((Rectangle)Template.FindName("TopCenter", this)).Fill;
_tRight = (ImageBrush)((Rectangle)Template.FindName("TopRight", this)).Fill;
_cLeft = (ImageBrush)((Rectangle)Template.FindName("CenterLeft", this)).Fill;
_c = (ImageBrush)((Rectangle)Template.FindName("Center", this)).Fill;
_cRight = (ImageBrush)((Rectangle)Template.FindName("CenterRight", this)).Fill;
_bLeft = (ImageBrush)((Rectangle)Template.FindName("BottomLeft", this)).Fill;
_b = (ImageBrush)((Rectangle)Template.FindName("BottomCenter", this)).Fill;
_bRight = (ImageBrush)((Rectangle)Template.FindName("BottomRight", this)).Fill;
Not sure why it throws an exception in the designer, but running the control shows it works
To avoid the designer exception just add a Template != null check in Loaded delegate:
Loaded += (s, e) =>
{
  ApplyTemplate();

  if (Template != null)
  {
    ...
  }
};
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: NineSlice control does not immediately work correctly.

28 Oct 2020, 04:43

That seems to work! Thanks for the help. Do you know why the control doesn't work in the editor? Is there anything I can change to fix this? I swear a previous version of this control was working in the editor when testing it in WPF, but I haven't been able to get it to work since then.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: NineSlice control does not immediately work correctly.

28 Oct 2020, 17:32

Do you know why the control doesn't work in the editor? Is there anything I can change to fix this?
As I mentioned in my previous post Blend designer was raising a NullReferenceException when executing your code in NineSliceControl.cs (line 83). The Template can be null there, so you need to check if (Template != null) before doing the FindName.

I also noticed that you have Control Display Options set to platform controls only, so your user control can't be rendered.
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: NineSlice control does not immediately work correctly.

30 Oct 2020, 09:19

No sorry, I understand that. I meant: why is my template null to begin with? Why can't the nine slice show in the editor?

> Control display options

Interesting, I haven't seen this before. I will try this.
 
asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Re: NineSlice control does not immediately work correctly.

30 Oct 2020, 09:24

Nevermind, I found it! It displays correctly now, thanks.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: NineSlice control does not immediately work correctly.

03 Nov 2020, 12:59

Glad it works now.
Just curious, what did you change to fix it?
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: NineSlice control does not immediately work correctly.

09 Nov 2020, 10:32

Hi, following this topic we developed our own version of nine slice control and shared it in our GitHub:

https://github.com/Noesis/Tutorials/tre ... /NineSlice

Hope this would help others in the future :)

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 88 guests