1

I am fairly new to Xamarin and XAML, so forgive me if my question is dumb.

I have an image that sits inside of an absolute layout content, the image is larger than the screen width and height (pinch and pan works). I am now trying to create a grid that sits on top of the image and eventually populate each cell with a button (a crude way of getting X,Y position). It is crude, I'll admit it, but I would like to do it, if anything, I'll learn what not to do.

This is my XAML,

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyProject.Code" 
             x:Class="MyProject.Views.myImage"
             HeightRequest="771"
             WidthRequest="900">

    <ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand">
            <local:PinchAndPanContainer>
                <Image Source="map.png"
                       HorizontalOptions="FillAndExpand"
                       VerticalOptions="FillAndExpand"
                       Aspect="Fill"
                       Opacity="50"/>

            </local:PinchAndPanContainer>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage> 

And this is my .cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyProject.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class myImage: ContentPage
    {
        public myImage()
        {            
            InitializeComponent();

            // Creates the grid
            InitializeGrid(2);
        }

        void InitializeGrid(int res)
        {
            Grid grid = new Grid();

            var red = new BoxView { Color = Color.Red };
            var grn = new BoxView { Color = Color.Green };
            var blu = new BoxView { Color = Color.Blue };
            var yel = new BoxView { Color = Color.Yellow };

            grid.WidthRequest = 900;
            grid.HeightRequest = 771;

            grid.VerticalOptions = LayoutOptions.FillAndExpand;
            grid.HorizontalOptions = LayoutOptions.FillAndExpand;

            for (int MyCount = 0; MyCount < res; MyCount++)
            {
                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            }

            grid.Children.Add(red, 0, 0);
            grid.Children.Add(grn, 0, 1);
            grid.Children.Add(blu, 1, 0);
            grid.Children.Add(yel, 1, 1);
        }
    }
}

How can I achieve a 2x2 grid that will sit on top of the image? I would like to take the C# route in creating the grid so I can create a loop and pass in the "resolution" of the grid, 3x3, 100x100, etc.

When I execute this, nothing happens. Even if I comment out almost the entire XAML that displays the image, I still get nothing. Not sure where to go from here.

Matt
  • 17
  • 4

1 Answers1

0

Add a name to your AbsoluteLayout (i.e. x:Name="layout") so you can parent your grid to it via .Children.Add

I made a few more changes to your InitializeGrid method to setup the grid within the AbsoluteLayout properly

FYI: Creating grids with a large number of elements will be a huge performance issue.

Example:

void InitializeGrid(int res)
{
    var grid = new Grid
    {
        RowSpacing = 0,
        ColumnSpacing = 0
    };
    AbsoluteLayout.SetLayoutBounds(grid, new Rectangle(1, 1, 1, 1));
    AbsoluteLayout.SetLayoutFlags(grid, AbsoluteLayoutFlags.All);

    for (int MyCount = 0; MyCount < res; MyCount++)
    {
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
    }

    grid.Children.Add(new BoxView { Color = Color.Red, Opacity=0.5 }, 0, 0);
    grid.Children.Add(new BoxView { Color = Color.Green, Opacity = 0.5 }, 0, 1);
    grid.Children.Add(new BoxView { Color = Color.Blue, Opacity = 0.5 }, 1, 0);
    grid.Children.Add(new BoxView { Color = Color.Yellow, Opacity = 0.5 }, 1, 1);

    layout.Children.Add(grid);
}

Output:

enter image description here

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • That is perfect, that is exactly what I was wondering, how the XAML made the connection to the C#, x:Name does the trick. Thank you very much. Follow up question, the only way to get the coords is via a custom renderer? I can't figure out how to implement one (I tried for a few days)... that is why I took this approach, but is that what you would suggest? – Matt Feb 01 '19 at 16:53
  • @Matt Touch coordinates are not available via Form's Views (a major longterm shortcoming IMHO), there are 3rd-parties like "MR.Gestures" that provide cross-platform gesture/touch events. If I am forced to use Forms, then yes, a per-platform custom renderer that is optimized to your needs is the way to go. – SushiHangover Feb 01 '19 at 17:05
  • Thanks, I am well aware of Mr Gestures, every single post recommends that. I am doing this for fun as a side little project. I don't want to pay for a license, it's doable without that library. – Matt Feb 01 '19 at 17:35