Xamarin Forms:我可以制作一个可以由不同页面动态更改的自定义模板吗?

时间:2019-03-01 23:19:17

标签: xaml xamarin

我正在尝试创建一种具有页眉和正文的模板,其中正文完全由页面实现,并且页眉具有可以由页面添加的区域。

我目前正在尝试一个看起来像这样的ControlTemplate:

  <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>

我可以在XAML视图和页面中使用此ControlTemplate来构建主体,但找不到任何访问LeftHeaderAreaRightHeaderArea来向其添加控件的方法。

1 个答案:

答案 0 :(得分:0)

我们决定让页眉定义所有可能的控件,只显示给定页面中可访问的控件,而不是让每个页面都将控件注入到页眉中。

例如,我的问题的RightHeaderArea已重构为如下形式:

        <StackLayout Spacing="10" HorizontalOptions="End" Orientation="Horizontal" Grid.Column="2">
          <svg:SvgCachedImage VerticalOptions="Center" WidthRequest="30" HeightRequest="30" 
                              IsVisible="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToBoolConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.ViewUploadHistory}}" 
                              Source="resource://Uploader.Images.icon-viewUploadHistory.svg">
            <svg:SvgCachedImage.GestureRecognizers>
              <TapGestureRecognizer Command="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToCommandConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.ViewUploadHistory}}" />
            </svg:SvgCachedImage.GestureRecognizers>
          </svg:SvgCachedImage>

          <svg:SvgCachedImage VerticalOptions="Center" WidthRequest="35" HeightRequest="35"
                              IsVisible="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToBoolConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.ViewUploadQueue}}" 
                              Source="resource://Uploader.Images.icon-viewUploadQueue.svg">
            <svg:SvgCachedImage.GestureRecognizers>
              <TapGestureRecognizer Command="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToCommandConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.ViewUploadQueue}}" />
            </svg:SvgCachedImage.GestureRecognizers>
          </svg:SvgCachedImage>

          <svg:SvgCachedImage Grid.Column="2" VerticalOptions="Center" WidthRequest="60" HeightRequest="50" 
                              IsVisible="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToBoolConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.Upload}}" 
                              Source="resource://Uploader.Images.icon-upload.svg">
            <svg:SvgCachedImage.GestureRecognizers>
              <TapGestureRecognizer Command="{TemplateBinding BindingContext.AvailableToolbarCommands, Converter={StaticResource tclsToCommandConverter}, ConverterParameter={x:Static mod:ToolbarCommandName.Upload}}" />
            </svg:SvgCachedImage.GestureRecognizers>
          </svg:SvgCachedImage>
        </StackLayout>

我所有的ViewModel都有一个公共属性AvailableToolbarCommands,它是一个List<ToolbarCommandLink>,其中ToolbarCommandLink是一个简单类,其中包含一个Command和一个自定义枚举值({{1 }}。

所有这些都是转换器。如果值(列表)包含名称与参数(ToolbarCommandName)匹配的ToolbarCommandLink,则ToolbarCommandName返回true; tclsToBoolConverter在其与参数相匹配的值(列表)中找到的ToolbarCommandLink中返回命令。