Search code examples
c#xamlmauicontroltemplate

How to access a child of a ControlTemplate applied to a ContentView of a ContentPage, from the ContentPage?


So I'm trying to design a page which can have two different appearances depending on a state defined at runtime. I don't have much experience with MAUI or XAML in general but I am trying to do it the right way, and so here is what I did:

  • I defined two ControlTemplate elements in the ContentPage's resources.
  • I defined the common UI in ContentPage's content, and defined a ContentView element that consumes the content from one of the two ControlTemplate elements, which is set in the xaml.cs code file of the page depending on the state of the ViewModel bound to it.

Here is the simplified XAML code from the page:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                   xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
                   xmlns:local="clr-namespace:MyApp"
                   >
<ContentPage.Resources>
    <ControlTemplate x:Key="template1">
        <Grid RowDefinitions="*,*,*">
            <Label Text="TEMPLATE1 UI..."/>
        </Grid>
    </ControlTemplate>
    
    <ControlTemplate x:Key="template2">
        <Grid RowDefinitions="*,*,*">
            <Label Text="TEMPLATE2 UI..."/>
            
            <!-- I need to access this element from MainPage.xaml.cs -->
            <local:MyCustomControl x:Name="myCustomControl"/>
        </Grid>
    </ControlTemplate>
</ContentPage.Resources>


<Grid RowDefinitions="*, *, *">
    <!-- Here goes my common UI -->
    <Label Grid.Row="1" Text="COMMON UI..."/>
    
    <!-- Here goes one of my two ControlTemplate UI -->
    <ContentView x:Name="contentFromTemplate" Grid.RowSpan="3" Grid.ColumnSpan="3"/>
</Grid>

Now as you can see, in "template2" ControlTemplate, there is a MyCustomControl element. I am trying to access this element from the cs code of the page but without any success. I understand that if the ControlTemplate was to be applied to the page, I could access it with the GetTemplateChild method, but that does not work in my case since the ControlTemplate is applied to a ContentView, in the page.

-> How can I access the "myCustomControl" element from MainPage.xaml.cs ?

I am unsure my approach is the correct one though, and I appreciate any input on a better one, thanks a lot for taking the time to read.


Solution

  • I am trying to avoid duplicating UI code as much as possible, and my two UI have a lot in common, simply some elements will go to a different position on the page depending on my ViewModel's state.

    As a summary, I will post an answer.

    For this problem, there are several ways to achieve this.

    1.Since there are a lot in common for the two UT, one common method is to show and hide some elements based on your view model.

    For example, you can set property IsVisible for your views:

     if(Your conditional statement is true)
          yourview.IsVisible = true;
      else
          yourview.IsVisible = false;
    

    2.another way is to use two separate pages depending on the ViewModel's state, just as H.A.H mentioned.