Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ItemsPanelTemplate TemplateBinding causes AVLN2000 compile error after upgrading from 11.2.0 to 11.2.1 #17553

Closed
ionite34 opened this issue Nov 18, 2024 · 6 comments

Comments

@ionite34
Copy link

Describe the bug

A TemplateBinding in a StackPanel within a ItemsPanelTemplate was working in 11.1.x and 11.2.0, after 11.2.1 update it causes this error:

Error AVLN2000 Avalonia: Unable to resolve suitable regular or attached property Spacing on type Avalonia.Controls:Avalonia.Controls.ItemsControl Line 36, position 37.

Seems TemplateBinding is resolving to the ItemsControl instead of the actual template control with the Spacing property, is this an intended behavior change?

Possibly related to #17483

To Reproduce

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Style Selector="controls|StackCard">
        <Setter Property="Template">
            <ControlTemplate>
                <ScrollViewer>
                    <ItemsControl>
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel 
                                    Spacing="{TemplateBinding Spacing}"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>
                </ScrollViewer>
            </ControlTemplate>
        </Setter>
    </Style>
</Styles>
public class StackCard : TemplatedControl
{
    public static readonly StyledProperty<int> SpacingProperty = AvaloniaProperty.Register<StackCard, int>(
        "Spacing",
        4
    );

    public int Spacing
    {
        get => GetValue(SpacingProperty);
        set => SetValue(SpacingProperty, value);
    }
}

Expected behavior

No response

Avalonia version

11.2.1

OS

Windows

Additional context

No response

@huangliu
Copy link

I had the same problem 😂.

@rabbitism
Copy link
Contributor

Is ItemsPanelTemplate considered part of ControlTemplate?

@MrJul
Copy link
Member

MrJul commented Nov 19, 2024

This one puzzled me for a moment, as this wasn't supposed to be a supported scenario. But if it worked in previous versions, that would indeed be a source breaking change that needs fixing...

It turns out this never really worked!
While the above XAML didn't produce a compilation error before 11.2.1, the binding wasn't working at runtime, because it was effectively targeting the ItemsControl, not the parent StackCard control.

This is easily verifiable. Adjust the bound Spacing: it simply doesn't work. Bind to a common property such as Background: the color comes from the ItemsControl, not the StackCard:

<Style Selector="local|StackCard">
  <Setter Property="Background" Value="OrangeRed" />
  <Setter Property="Spacing" Value="32" />
  <Setter Property="Template">
    <ControlTemplate>
      <ScrollViewer>
        <ItemsControl Background="DodgerBlue">
          <ItemsControl.ItemsSource>
            <generic:List x:TypeArguments="x:String">
              <x:String>Abc</x:String>
              <x:String>Def</x:String>
            </generic:List>
          </ItemsControl.ItemsSource>
          <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
              <StackPanel
                Height="100"
                Background="{TemplateBinding Background}"
                Spacing="{TemplateBinding Spacing}" />
            </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
        </ItemsControl>
      </ScrollViewer>
    </ControlTemplate>
  </Setter>
</Style>

I've tested 11.0.13, 11.1.4 and 11.2.0 and they all exhibit the same behavior here: the TemplatedParent is the ItemsControl at runtime, despite the compiler thinking otherwise.
In 11.2.1, the compiler now properly informs you that the binding isn't correct.

Plus, in 11.2.1 you can now use a TemplateBinding inside ItemsPanelTemplate when it's outside of a Style or ControlTemplate (for example as a local).

ItemsPanelTemplate and ControlTemplate now have the exact same behavior as far as bindings are concerned.

Here's a summary table showing the resolved TemplatedParent type for a TemplateBinding inside ItemsPanelTemplate depending on its scope:

Scope 11.0.x 11.1.x 11.2.0 11.2.1
ControlTemplate (runtime) ✔️ ItemsControl ✔️ ItemsControl ✔️ ItemsControl ✔️ ItemsControl
ControlTemplate (compiler) ❗ Parent control ❗ Parent control ❗ Parent control ✔️ ItemsControl
Style for ItemsControl ✔️ ItemsControl ✔️ ItemsControl ❌ Error ✔️ ItemsControl
Local value ❌ Error ❌ Error ❌ Error ✔️ ItemsControl

(Edit: removed the resource row, as it doesn't work as expected.)

@ionite34
Copy link
Author

Thanks for the detailed investigation @MrJul, can confirm in our project it seems the Spacing property never bound effectively before either. I think this can just be closed then? Unless @huangliu sees some different behavior.

For the binding I intended to do, should it be using something like Spacing="{Binding $parent[controls:StackCard].Spacing}" instead?

@MrJul
Copy link
Member

MrJul commented Nov 21, 2024

Thanks for the detailed investigation @MrJul, can confirm in our project it seems the Spacing property never bound effectively before either.

Thanks for confirming! I'm closing this issue.

For the binding I intended to do, should it be using something like Spacing="{Binding $parent[controls:StackCard].Spacing}" instead?

Indeed, that would be the correct way to proceed.

@MrJul MrJul closed this as completed Nov 21, 2024
@Querzion
Copy link

Querzion commented Dec 22, 2024

I keep getting this error over and over again.

0>UserListView.axaml(47,37): Error AVLN2000 Avalonia: Unable to resolve property or method of name 'GoToDetailsView' on type 'System.Object'. Line 47, position 37.
0>------- Finished building project: MA_Presentation_MVVM_Avalonia. Succeeded: False. Errors: 1. Warnings: 0
Build completed in 00:00:01.019

I'm learning web development, and I daily drive Linux, so I can't really use WPF etc. so I went the Avalonia route, because I thought It was mature enough to use based on the applications and info I could find. There's been a lot of frustration this past week, because I've only used Avalonia this week, while the others are learning about WPF. I have no idea how to resolve this and ChatGPT only gave me answers that aligned with what I had already done.

Also there's been a bit of a problem with other stuff, ChatGPT keeps telling me that ListView & PasswordBox should exist and work, but It doesn't really seem like that since their responding classes doesn't show up as an alternative, so I have to make due with what shows up. This is the code that I have problem with, it should work, but it doesn't, so I must have done something wrong which is more likely since I'm new to this and is learning, OR Avalonia is borked. "/

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             
             xmlns:local="clr-namespace:MA_Presentation_MVVM_Avalonia.Views"
             xmlns:viewModels="clr-namespace:MA_Presentation_MVVM_Avalonia.ViewModels"
             xmlns:models="clr-namespace:Business.Models;assembly=Business"
             d:DataContext="{d:DesignInstance Type=viewModels:UserListViewModel}"
             x:DataType="viewModels:UserListViewModel"
             
             
             mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="450"
             x:Class="MA_Presentation_MVVM_Avalonia.Views.UserListView">
    
    <Grid Margin="15">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            
            <TextBlock Grid.Column="0" Text="User List" FontSize="20" FontWeight="Bold"/>
            <Button Grid.Column="1" Command="{Binding GoToAddViewCommand}" Content="&#x2795;" Padding="10 5"/>
        </Grid>
        
        <ListBox Grid.Row="1" ItemsSource="{Binding Users}" Margin="0 20 0 0 " HorizontalAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="models:User">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        
                        <StackPanel Grid.Column="0">
                            <TextBlock Text="{Binding DisplayName}" />
                            <TextBlock Text="{Binding Email}" FontSize="10" />
                        </StackPanel>
                        
                        <StackPanel Grid.Column="1">
                            <Button Command="{Binding DataContext.GoToDetailsViewCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                    CommandParameter="{Binding .}"
                                    Content="&#x2026;" Padding="8 5" />
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
    
</UserControl>

This snippet is the problem child here. . .

<StackPanel Grid.Column="1">
                            <Button Command="{Binding DataContext.GoToDetailsViewCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                    CommandParameter="{Binding .}"
                                    Content="&#x2026;" Padding="8 5" />
                        </StackPanel>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants