.NET Maui: Can‘t access image from ContentView

AAA BBB 41 Reputation points
2024-06-25T19:23:35.9966667+00:00

Hello,

i have trouble trying to access View (image) in C# code. .NET Maui is used, now migrating from Xamarin Forms. Maybe someone will be able to help me.

So what I have done:

1.       Created root folder “MyTemplates” in my “AngryFish” project.

2.       Created files “MyStatusToolbar.xaml” and ” MyStatusToolbar.xaml.cs” in “MyTeplates” folder.

3.       File “MyStatusToolbar.xaml” contains ContentView which has “ButtonReadAllData“ image.

4.       Created root folder “PagesStandard” in my “AngryFish” project.

5.       Created files “ConnectionAndUpdate.xaml” and ”ConnectionAndUpdate.xaml.cs” in “PagesStandard” folder.

6.       Added xmlns:controls="clr-namespace:AngryFish.MyTemplates" link to „MyTemplates“ folder at the top of “ConnectionAndUpdate.xaml” file. Then added line <controls:MyStatusToolbar Grid.Row="0"/> to pass content from “MyStatusToolbar.xaml” file to the  “ConnectionAndUpdate.xaml” file.  Content is displayed fine.

7.       I wanted to attach GestureRecognizer to the image in the ”ConnectionAndUpdate.xaml.cs” file. Image is shown in the “ConnectionAndUpdate.xaml” file and is coded in the “MyStatusToolbar.xaml” file as mentioned earlier. Application compiles fine, but when i run it, i get an error before app is loaded:

error

I think i am missing some references to the Image object.

In the picture you can see how files tree looks:

Files directory

My MyStatusToolbar.xaml file:

<StackLayout Orientation="Vertical" Spacing="0">

       <!--This layout sets color for the toolbar-->

        <StackLayout 

            HorizontalOptions="Fill"  

            BackgroundColor="#A0A096">

            <!--This layout pushes all controls to the end-->

            <StackLayout 

                Orientation="Horizontal" 

                HorizontalOptions="End" 

                Padding="5">

              

                <Image 

                       x:Name="ButtonReadAllData"

                        Margin="0,0,0,0"
                        Aspect="AspectFit"

                       Source="other_refresh_button.png"

                        WidthRequest="40"

                       HeightRequest="40"

                        VerticalOptions="Center">

                    </Image>

            </StackLayout>

        </StackLayout>
        <!--draw thin line below all controls-->

        <BoxView 

            HeightRequest = "1"  

            BackgroundColor="#556b2f"/>

    </StackLayout>

</ContentView

My MyStatusToolbar.xaml.cs file:

namespace AngryFish.MyTemplates;

public partial class MyStatusToolbar : ContentView

{

	public MyStatusToolbar()

	{

		InitializeComponent();

	}

}

My ConnectionAndUpdate.xaml file:

<?xml version="1.0" encoding="utf-8" ?>

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"

                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

                 BackgroundColor="{StaticResource BackgroundDarkGreen}"
                 x:Class="AngryFish.PagesStandard.ConnectionAndUpdate"

                 xmlns:controls="clr-namespace:AngryFish.MyTemplates"

                 Title="Connection and update">

    <Grid 

          RowDefinitions="Auto,*"

          Style="{StaticResource MainGrid}">

        <!--Add status toolbar-->

        <controls:MyStatusToolbar Grid.Row="0"/>

        <!--MainScrollView-->

        <ScrollView 

            Orientation="Vertical"

            Grid.Row="1"

            Style="{StaticResource MainScrollView}">

           <StackLayout

              Style="{StaticResource MainScrolledContent}">

            </StackLayout>

        </ScrollView>

    </Grid>

</ContentPage>

My ConnectionAndUpdate.xaml.cs file:

using AngryFish.CodeFiles;
using Microsoft.VisualBasic;
using System.Net;

namespace AngryFish.PagesStandard;

public partial class ConnectionAndUpdate : ContentPage

{

    //########################## CREATE CLASS INSTANCES/OBJECTS ##########################

    //Initialise TapGestureRecogniser objects

     TapGestureRecognizer _TapGestureRecognizer = new TapGestureRecognizer();

    ApplicationState _ApplicationState = new ApplicationState();

    TcpTransmission _TcpTransmission = new TcpTransmission();

    

    //############################### INITIALISE VARIABLES ###############################`

    //Initialise views for status toolbar

    Image _ButtonReadAllData;
    public ConnectionAndUpdate()

    {

        InitializeComponent();

        //Get views for status toolbar

        _ButtonReadAllData = (Image)GetTemplateChild("ButtonReadAllData");

        //############################ ATTACH EVENTS TO THE VIEWS ############################

       //add tap event to the ButtonReadAllData control

        //_ButtonReadAllData.GestureRecognizers.Add(_TapGestureRecognizer);

    }

        

    //########################### CREATE CUSTOM EVENTS HANDLERS ##########################

    async void _TapGestureRecognizer_Tapped(Object sender, EventArgs e)

    { 

        if (sender == _ButtonReadAllData)

        {

           //if TCP socket is closed and command to send / receive data was sent, throw warning message

            if (TcpTransmission.CheckIfTcpSocketConnected(TcpTransmission._tcpClient) == false)

            {

              _ApplicationState.PendingMessageNumber = 2; 

            }

        }        

    }       

}
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,923 questions
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,607 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 76,551 Reputation points Microsoft Vendor
    2024-06-26T03:37:25.1033333+00:00

    Hello,

    I can get the same error by using GetTemplateChild. However, you can get the all controls in the ContentView by GetVisualTreeDescendants, then traverse all control types and judge the control's type, if the type is Image and set GestureRecognizers the like following code.

    List<IVisualTreeElement> listStatusToolbar = (List<IVisualTreeElement>)myStatusToolbar.GetVisualTreeDescendants();
    foreach (IVisualTreeElement image in listStatusToolbar)
    {
         if (image is Image)
         {
              _ButtonReadAllData = (Image)image;
             _ButtonReadAllData.GestureRecognizers.Add(_TapGestureRecognizer);
             _TapGestureRecognizer.Tapped += _TapGestureRecognizer_Tapped;
     
     
         }
    }
    

    As note: please do not forget to add x:Name="myStatusToolbar" for controls:MyStatusToolbar

      <controls:MyStatusToolbar x:Name="myStatusToolbar" Grid.Row="0"/>
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.