Cedric Royer-Bertrand
Cedric Royer-Bertrand

Reputation: 741

Avalonia Canvas: ItemControl do not set Canvas.Top or Canvas.Left

I'm using Avalonia 11 and trying to draw shapes on a Canvas using ItemsControl. The problem is that the properties Canvas.Left and Canvas.Top are not being taken into account.

View:

<Canvas Width="{Binding Width}" Height="{Binding Height}" MaxWidth="200" MaxHeight="100" Background="Yellow" Margin="3">
    <Rectangle Fill="Blue" Height="10" Width="10" Canvas.Left="50" Canvas.Top="50"/>
    <ItemsControl ItemsSource="{Binding Tiles}" >
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Rectangle Fill="Green" Height="{Binding Size}" Width="{Binding Size}" 
                           Canvas.Left="{Binding TopY}" Canvas.Top="{Binding TopY}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Canvas>

ViewModel

public record CanvasTile(int Size, int TopX, int TopY);

public ObservableCollection<CanvasTile> Tiles { get; }

Tiles.Add(new CanvasTile(TILE_SIZE, 1 * TILE_SIZE, 1 * TILE_SIZE));
Tiles.Add(new CanvasTile(TILE_SIZE, 2 * TILE_SIZE, 2 * TILE_SIZE));
Tiles.Add(new CanvasTile(TILE_SIZE, 4 * TILE_SIZE, 4 * TILE_SIZE));

Debug

enter image description here

Result As you can see the green rectangles defined by the ItemControl are not at the right place. The blue rectangle is at the right place (I hardcoded his position outside of the (see code above)

enter image description here

Expected Result I've hardcoded the expected result to show what I should have get.

enter image description here

Upvotes: 0

Views: 509

Answers (1)

Tarazed
Tarazed

Reputation: 2675

ItemsControl creates it's own parent panel to display the items in. By default, this is a StackPanel which you can see here. So what you actually have is a Canvas that contains a rectangle and a StackPanel, and that StackPanel contains 3 more rectangles.

You can change the panel with the ItemsPanel property. However, you won't be able to add your blue rectangle to this canvas in XAML. You might want to add it to your items collection and bind the color to a property in the object.

<ItemsControl ItemsSource="{Binding Tiles}" >
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas Width="{Binding Width}" Height="{Binding Height}" MaxWidth="200" MaxHeight="100" Background="Yellow" Margin="3" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Rectangle Fill="Green" Height="{Binding Size}" Width="{Binding Size}" Canvas.Left="{Binding TopY}" Canvas.Top="{Binding TopY}"/>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

Upvotes: 0

Related Questions