Getting access to Popup template controls during runtime

Hi,

I am using a Syncfusion.Maui.Popup with the following simple ContentTemplate:

<sfpopup:SfPopup.ContentTemplate>
<DataTemplate>
<Editor x:Name="SelectionTextEditor"
Text="{Binding SelectionText}" />
</DataTemplate>
</sfpopup:SfPopup.ContentTemplate>


In Xamarin I used the following code to get the editor control during runtime:

var nativeObject = (object)this.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("NativeObject")).GetValue(this);

var formsPopupviewContentTemplate = nativeObject.GetType().GetRuntimeFields().FirstOrDefault(x => x.Name.Equals("formsPopupViewContentTemplate")).GetValue(nativeObject);

editorControl = (formsPopupviewContentTemplate as Layout)?.FindByName<View>("SelectionTextEditor");


However, in Maui the Popup doesn't seem to contain a "NativeObject" property so this code fails.

How can I get the Editor control during runtime in Maui?

Thank you,

Alfredo Diaz


15 Replies

SY Suthi Yuvaraj Syncfusion Team January 30, 2024 09:13 PM UTC

Hi Alfredo,

We have checked your requirement, you can access the elements inside the ContentTemplate with two different approaches,

In ContentTemplate, behavior is added to the parent of the element that needs to be accessed.

Code snippet

In Xaml:

<popup:SfPopup x:Name="popup" >

    <popup:SfPopup.ContentTemplate>

        <DataTemplate>

            <StackLayout>

                <StackLayout.Behaviors>

                    <localStackBehavior/>

                </StackLayout.Behaviors>

                <Editor x:Name = "Editor" Text="Enter credentials" />

                <Label Text="Incorrect credentials" VerticalOptions="Center"/>

            </StackLayout>

        </DataTemplate>

    </popupSfPopup.ContentTemplate>

</popupSfPopup>


Approach 1:

In the ChildAdded event, you will get the instance of Entry(example related to the above code snippet).

Code snippet:

public class StackBehavior: Behavior<StackLayout>

{

protected override void OnAttachedTo(BindableObject bindable)

{

    stack = bindable as StackLayout;

    stack.ChildAdded += Stack_ChildAdded;

}

//Method 1: Get SfListView reference using Stack.ChildAdded Event

private void Stack_ChildAdded(object sender, ElementEventArgs e)

{

    if (e.Element is Editor)

    {

        entry = e.Element as Editor;

        //do the code

    }

}

}


Approach 2:

You can also get the Entry using the FindByName method from the Parent element.

Code Snippet:

public class StackBehavior: Behavior<StackLayout>

{

protected override void OnAttachedTo(BindableObject bindable)

{

    stack = bindable as StackLayout;

    entry = stack.FindByName<Editor>("Editor");

}

}


Also, we have attached the workable sample for your reference, Kindly let us know if you have any concerns.


Regards,

Suthi Yuvaraj


Attachment: MAUIPopup_(3)_69e0bf72.zip


AL Alfredo January 30, 2024 10:18 PM UTC

Thank you for the info Suthi!

Is there no way to get it after the page has been presented?  For example, after a user clicks a button (in the ButtonClicked event)?

For example, if you have a page with the following:

<VerticalStackLayout >
<Entry x:Name="MyEntry" />
<Button x:Name="MyButton"
Clicked="MyButton_Clicked" />
</VerticalStackLayout>


Can you get it in the MyButton_Clicked event?

private void MyButton_Clicked(object sender, EventArgs e)
{
// Get the Entry control here.
}




RM RiyasHameed MohamedAbdulKhader Syncfusion Team January 31, 2024 11:16 AM UTC

Hi Alfredo,

We would like to let you know that the elements inside data template (Popup.ContentTemplate) are not instantiated until they are actually used to render (i.e Popup view is opened) ,so the elements don't exist in the visual tree until then, which makes them inaccessible by x: Name through button_click event directly.

This can be achieved by invoking the childAdded event on the root element within the ContentTemplate of the popup, allowing you to get its child elements and to access through button_click action. We have attached code snippet and sample for your reference.

XAML

<Button Text="GetEntryControl"

        HeightRequest="50"

        VerticalOptions="Start"

        HorizontalOptions="Center"

        Clicked="Button_Clicked" />

<popup:SfPopup x:Name="popup">

    <popup:SfPopup.ContentTemplate>

        <DataTemplate>

            <StackLayout x:Name="stackLayout"

                            ChildAdded="StackLayout_ChildAdded">

                <Entry x:Name="Entry"

                        Text="MyText" />

            </StackLayout>

        </DataTemplate>

    </popup:SfPopup.ContentTemplate>

</popup:SfPopup>

C#
         
Entry entry;

    private void StackLayout_ChildAdded(object sender, ElementEventArgs e)

    {

        if (e.Element is Entry)

        {

            var child = (Entry)e.Element;

            if (child != null && child.StyleId == "Entry")

            {

                entry = child;

            }

        }

    }

       private void Button_Clicked(object sender, EventArgs e)

       {

          entry.Text = "Hello";

       }


Regards,

Riyas Hameed M



Attachment: MAUIPopup_3b13f3c8.zip


AL Alfredo January 31, 2024 01:57 PM UTC

Thank you for the information Riyas, that is helpful.

Last question - what if I want to get the editor in the Opened event for the PopupLayout itself?  For example, if I have a simple Popup:

<sfpopup:SfPopup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 xmlns:sfpopup="clr-namespace:Syncfusion.Maui.Popup;assembly=Syncfusion.Maui.Popup"
 Opened="OnPopupOpened"
 x:Class="Tabular.App.Views.Popups.EntryPopupBase">
<sfpopup:SfPopup.ContentTemplate>
<DataTemplate>
<Editor x:Name="SelectionTextEditor" />
</DataTemplate>
</sfpopup:SfPopup.ContentTemplate>
</sfpopup:SfPopup>


And I have the following Opened event handler:

protected virtual void OnPopupOpened(object sender, EventArgs e)
{
    // Get the editor here.
}

The popup has been instantiated and opened.  Is there a way to get the Editor control in the Opened event handler of the Popup itself?



SY Suthi Yuvaraj Syncfusion Team February 1, 2024 04:25 PM UTC

Alfredo,

We would like to let you know that the Popup opened event will trigger and layout on the popup view simutaneously,   elements inside the data template (Popup.ContentTemplate) are not instantiated until they are actually used to render (i.e Popup view is opened) , so the elements don't exist in the visual tree until then.We have checked your requirement, you can read and write the entry text in the code behind, Please refer to the below code snippet for more reference.

In code behind:


private void StackLayout_ChildAdded(object sender, ElementEventArgs e)      

{ {

if (e.Element is Editor)

        {

            var child = (Editor)e.Element;

            if (child != null && child.StyleId == " Editor ")

            {

                editor = child;

            }

        }

    }


    private void popup_Opened(object sender, EventArgs e)

    {

        if (editor != null)

        {

            entry.Text = "Enter the Value";

           

        }

    }

If you are still facing any issues, kindly let us know the exact requirements to find the appropriate solution.



AL Alfredo February 1, 2024 04:57 PM UTC

Thank you for your response Suthi - that will work. Thanks for all the great info, you guys have been great as always!

Alfredo Diaz



SY Suthi Yuvaraj Syncfusion Team February 2, 2024 04:11 PM UTC

Alferdo Diaz,

We are glad to know that your issue has been fixed. Please let us know if you have any other queries. We will be glad to assist you.



AL Alfredo February 19, 2024 03:29 PM UTC

Hello Suthi,

I have a question regarding your solution above.  You indicated that I can grab the Editor instance inside the StackLayout_ChildAdded event.  However, there is no StackLayout inside the Popup's ContentTemplate, only an Editor:

<sfpopup:SfPopupxmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 xmlns:sfpopup="clr-namespace:Syncfusion.Maui.Popup;assembly=Syncfusion.Maui.Popup"
 Opened="OnPopupOpened"
 x:Class="Tabular.App.Views.Popups.EntryPopupBase">
<sfpopup:SfPopup.ContentTemplate>
<DataTemplate>
<Editor x:Name="SelectionTextEditor"/>
</DataTemplate>
</sfpopup:SfPopup.ContentTemplate>
</sfpopup:SfPopup>

How can I get the instance of the Editor in this case?



SY Suthi Yuvaraj Syncfusion Team February 21, 2024 02:45 PM UTC

Alfredo, 

We would like to let you know that you cannot directly access the element inside the datatemplate, In this case you can achieve your requirement by using reflection,Please refer the below code snippet for more reference.

Code snippet:

public MainPage()

{

    InitializeComponent();

    this.Loaded += MainPage_Loaded;


}


private void MainPage_Loaded(object? sender, EventArgs e)

{

    var popupView = popup.GetType().GetField("PopupView", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(popup);

    var popupMessageView = popupView.GetType().GetField("PopupMessageView", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(popupView);

    var editor = (popupMessageView as SfContentView).Content as Entry;

    editor.Text = "New Value";

}




AL Alfredo March 3, 2024 03:36 PM UTC

Hi Suthi,

I finally had a chance to try out your solution and it worked great - thank you for your assistance.  Your controls are wonderful, and your support is excellent!

Regards,

Alfredo



SY Suthi Yuvaraj Syncfusion Team March 4, 2024 11:24 AM UTC

Alfredo,

We are glad that the provided response meets your requirement. Please let us know if you need further assistance. As always, we are happy to help you out. 



SM Socorrito Moorlag replied to Suthi Yuvaraj July 18, 2025 10:22 AM UTC

Thank you Suthi,

using <StackLayout.Behaviors>  is working for me in order to set the focus to my entry

Also I am using :

            if (entry != null)

            {

                stack.Loaded += (s, e) =>

                {

                    MainThread.BeginInvokeOnMainThread(() => entry.Focus());

                };

            }



AP Abinesh Palanisamy Syncfusion Team July 21, 2025 01:08 PM UTC

Hi Socorrito,

We are glad to know that the problem has been resolved at your end. Please let us know if you have any further queries on this. We are happy to help.
Regards,
Abinesh P


TK Tom Kusnierek replied to RiyasHameed MohamedAbdulKhader December 9, 2025 09:46 PM UTC

This worked for me.  Note, I had to add the public variable 'entry' to the public partial class above.



MM Muthukumar Madasamy Syncfusion Team December 12, 2025 05:08 AM UTC

Hi Tom,

We are glad to know that the provided solution worked for you and the reported problem has been resolved at your end. Thank you for sharing the additional note about adding the public variable to the partial class. it will definitely help others with similar scenarios.

Please let us know if you have any further queries or need assistance with anything else. We are happy to help!

Best Regards,
Muthu Kumar Madasamy.

Loader.
Up arrow icon