Forum Xamarin.Forms

Can I make a custom template that can be dynamically altered by different pages?

AaronTAaronT Member ✭✭
edited March 2019 in Xamarin.Forms

I'm trying to create a sort of template that has a header and body where the body is fully implemented by a page and the header has areas that can be added to by the page.

I'm currently experimenting with a ControlTemplate which look like this:

  <ControlTemplate x:Key="HeaderTemplate">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="10*" />
        <RowDefinition Height="90*" />
      </Grid.RowDefinitions>

      <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="10*" />
          <ColumnDefinition Width="60*" />
          <ColumnDefinition Width="30*" />
        </Grid.ColumnDefinitions>

        <BoxView BackgroundColor="{DynamicResource PrimaryColor}" Grid.ColumnSpan="3" />

        <StackLayout x:Name="LeftHeaderArea" Orientation="Horizontal" Grid.Column="0" />
        <Label Text="{DynamicResource HeaderTitle}" TextColor="White" VerticalOptions="Center" Grid.Column="1" />
        <StackLayout x:Name="RightHeaderArea" Orientation="Horizontal" Grid.Column="2" />
      </Grid>

      <ContentPresenter Grid.Row="1" />
    </Grid>
  </ControlTemplate>

I can use this ControlTemplate in my XAML views and pages to build the body, but I haven't found any way to access LeftHeaderArea or RightHeaderArea to add controls to them.

I'm just looking for anything that I can use for a template so that, ideally, on an individual page I can specify that I'm using the custom template and just define what goes in the LeftHeaderArea, RightHeaderArea, and body.

Is this possible?

Tagged:

Best Answer

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    You're looking at it from the wrong direction.
    Don't try to shove things into the header at runtime. This is 2002.

    Instead define the template so it pulls in what it needs from the ViewModel. Let it be responsible for itself. Don't make the page responsible for the template. Thus what we call separation of responsibility.

    Let the header take care of itself by grabbing the ToolTrayItemsCollection from your ViewModel... Or let build what it needs from a ModeEnumeration property... etc.

  • AaronTAaronT Member ✭✭
    edited March 2019

    @ClintStLaurent said:
    You're looking at it from the wrong direction.
    Don't try to shove things into the header at runtime. This is 2002.

    Instead define the template so it pulls in what it needs from the ViewModel. Let it be responsible for itself. Don't make the page responsible for the template. Thus what we call separation of responsibility.

    Let the header take care of itself by grabbing the ToolTrayItemsCollection from your ViewModel... Or let build what it needs from a ModeEnumeration property... etc.

    That makes sense. I was hoping, though, for a way to do it all in XAML so that a designer could create and stylize buttons and bind them to commands without having to go into actual code. If in the ViewModel I define the collection of controls to add to the header doesn't that mean I'm adding View data to the ViewModel; does that go against the MVVM pattern?

    Assuming that I use your suggestion and have the header pull necessary info from the ViewModels: does the ControlTemplate just get that data from bindings?

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I was hoping, though, for a way to do it all in XAML so that a designer could create and stylize buttons and bind them to commands without having to go into actual code.

    Yeah. That should be fine. Not seeing a problem.

    If in the ViewModel I define the collection of controls

    Stop. Nobody said to define controls in the ViewModel. That's way wrong. ViewModels are completely unaware of what UI exists. When I mentioned a collection of tool try items I was vague and maybe misleading. That should be a collection of actions or permissions - that your UI could turn into tools. You say a user can save, load, export, upload... whatever - those are not controls. They are permissions or commands etc. The UI decides for itself how that is to be presented. Maybe its a tool tray.... or context menu... or buttons... or images with tap guesture... The ViewModel doesn't know how its being presented: Only that the user has the okay to do it.

  • AaronTAaronT Member ✭✭

    That should be a collection of actions or permissions - that your UI could turn into tools. You say a user can save, load, export, upload... whatever - those are not controls. They are permissions or commands etc. The UI decides for itself how that is to be presented. Maybe its a tool tray.... or context menu... or buttons... or images with tap guesture...

    This is exactly what I want to do. My ViewModels already have commands and I can easily add collections that indicate which commands are accessible from the header toolbar; I just don't know how the ControlTemplate is going to display the correct controls based on those commands.

    For example, one VM has two commands (Upload and Cancel) that need to be invoked via an upload icon and a cancel icon in the header while another VM only has one command (View Queue) that needs to be invoked by an icon in the header. If I need can't create those icons in the respective Views then I'm not sure how to do it.

Sign In or Register to comment.