uno.extensions icon indicating copy to clipboard operation
uno.extensions copied to clipboard

How to draw elements of ItemsControl on Canvas using C# Markup

Open kucint opened this issue 10 months ago • 2 comments

@kucint I think it would be better if this issues with 3 questions was split into 3 discussions for easier tracking

Originally posted by @francoistanguay in https://github.com/unoplatform/uno/discussions/14947#discussioncomment-8930265

kucint avatar Apr 02 '24 12:04 kucint

I want to show the content of ItemsControl on Canvas as a collection of rectangles. To do so I produced following code:

public sealed partial class MainPage : Page
{
    public MainPage() => this
            .Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush"))
            .Content(ContentB());

    private static UIElement ContentA()
        => new Canvas()
        .Width(800)
        .Height(600)
        .Background(Colors.LightGray)
        .Children(
            new Rectangle()
            .Stroke(Colors.LightGray)
            .StrokeThickness(1)
            .Width(100).Height(50)
            .Fill(Colors.White)
            .Canvas(left: 100, top: 100),

            new Rectangle()
            .Stroke(Colors.LightGray)
            .StrokeThickness(1)
            .Width(100).Height(50)
            .Fill(Colors.DarkKhaki)
            .Canvas(left: 200, top: 100));

    private static UIElement ContentB()
        => new ItemsControl()
        .ItemsPanel(
            () => new Canvas()
            // uncommenting any of the following lines will cause the app to crash
            //.Width(250)
            //.Height(250)
            //.Background(Colors.DarkBlue)
            )
        .ItemsSource(new Node[]
        {
            new(new SolidColorBrush(Colors.DarkMagenta)),
            new(new SolidColorBrush(Colors.BlanchedAlmond)),
            new(new SolidColorBrush(Colors.HotPink))
        })
        .ItemTemplate<Node>(
            item => new Rectangle()
                .Stroke(Colors.LightGray)
                .StrokeThickness(1)
                .Width(100).Height(50)
                .Fill(() => item.Brush)       // using binding rather than direct value which is always null
            );
}

public sealed record Node(Brush Brush);

Question: How should I correctly create a Canvas that draws elements delivered by ItemsControl?

Two methods are provided here:

  • ContentA() that creates directly a canvas with rectangles -> this one is working as expected
  • ContendB() that creates ItemsControl as a container of Node that shall be represented in Canvas as Rectangles -> this one does not work as expected. You can see on screenshot below that StackLayout is still in action:

image

What am I missing?

See attached uno project that reproduces this issue: UnoCanvasApp.16090.zip

kucint avatar Apr 02 '24 13:04 kucint

this topic seems to be related to https://github.com/unoplatform/uno/issues/16046

kucint avatar Apr 02 '24 13:04 kucint

@dansiegel thoughts?

nickrandolph avatar May 07 '24 05:05 nickrandolph

This should have already been addressed via unoplatform/uno#16046 @kucint if this is still an issue for you please feel free to reopen and we can address anything that is outstanding.

dansiegel avatar May 07 '24 12:05 dansiegel