1

I want to draw some rectangles into an outer one. Coordinates (X, Y, Width, Height) and some more parameters like background colors are given by a View Model.

The result should look like

resulting pattern

I tried AbsoluteLayout and CollectionView (see this post). However, this does not work because AbsoluteLayout.LayoutBounds has no effect except on direct chidren of the AbsoluteLayout.

I would populate the screen in Code Behind but perhaps there is a more elegant way using Model View ViewModel and DataBinding?

  • are there a variable number of rectangles? Then try https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/bindable-layouts – Jason Mar 09 '23 at 19:01
  • I assume the layout has to be AbsoluteLayout (not CollectionView), for AbsoluteLayout.LayoutBounds to have an effect. – ToolmakerSteve Mar 09 '23 at 21:50

1 Answers1

0

Yes, AbsoluteLayout.LayoutBounds has no effect if used it in DataTemplate of CollectionView. So I am not going to use an AbsoluteLayout any more. I am gonna use StackLayout with Margin. (I know your UI could be far more complex than what I've done and I just want to share my idea here).

Here is my xaml,

<StackLayout BackgroundColor="Pink"  >
    <Frame Margin="10,10,0,0" HorizontalOptions="Start"  BackgroundColor="green" HeightRequest="100"    WidthRequest="50" />
    <CollectionView ItemsSource="{Binding ItemCollection}" SelectionMode="None">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <ContentView>
                    <Frame Margin="{Binding Margin}" HeightRequest="{Binding Height}"
                            WidthRequest="{Binding Width}"
                            HorizontalOptions="Start"
                            BackgroundColor="LightSalmon" >
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
                        </Frame.GestureRecognizers>
                    </Frame>
                 </ContentView>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

In my example, I bind the Margin, Height, Width of each rectangle to ViewModel. And for ViewModel:

public class MainPageViewModel
{

    public ObservableCollection<Item> ItemCollection { get; set; } = new ObservableCollection<Item>(); 

    public MainPageViewModel()
    {
        ItemCollection.Add
            (
                new Item
                {
                    Height = 50,
                    Weight = 100,
                    Margin = new Xamarin.Forms.Thickness(50, 0, 0, 0)

                }
            );
        ItemCollection.Add
            (
                new Item
                {
                    Height = 100,
                    Weight = 50,
                    Margin = new Xamarin.Forms.Thickness(100, 50, 0, 0)

                }
            );
        ItemCollection.Add
            (
                new Item
                {
                    Height = 100,
                    Weight = 50,
                    Margin = new Xamarin.Forms.Thickness(150, 50, 0, 0)

                }
            );
    }
}

I don't know if it is elegant enough or not, but it is the only way i can think of using MVVM for your case. By the way, go through the collection and add each control one by one in C# is also a good way.

Hope it works for you.

Liqun Shen-MSFT
  • 3,490
  • 2
  • 3
  • 11