首页 > 解决方案 > 如何通过传入类型参数来自定义 Xamarin 模板?

问题描述

这是我到目前为止提出的方法。然而,这似乎不是一个干净的解决方案。

有没有人有任何建议我可以想出一个更好的解决方案来做到这一点?

<?xml version="1.0" encoding="utf-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:local="clr-namespace:Japanese;assembly=Japanese" 
             x:Class="Japanese.Templates.HeaderTemplate" 
             x:Name="this" HorizontalOptions="FillAndExpand" Orientation="Vertical" Spacing="0" Margin="0">
    <StackLayout IsVisible="{Binding HeaderType, Converter={StaticResource HeaderType1BoolConverter}, Source={x:Reference this}  }" >
        <!-- code -->
    </StackLayout>
    <StackLayout IsVisible="{Binding HeaderType, Converter={StaticResource HeaderType2BoolConverter}, Source={x:Reference this}  }" >
        <!-- code -->
    </StackLayout>
</StackLayout>

在我的银行端 CS:

using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace Japanese.Templates
{
    public partial class HeaderTemplate : StackLayout
    {
        public HeaderTemplate()
        {
            InitializeComponent();
        }

   public static readonly BindableProperty HeaderTypeProperty =
        BindableProperty.Create(
            nameof(HeaderType),
            typeof(string),
            typeof(DataViewCellTemplate),
            default(string));

    public string HeaderType
    {
        get { return (string)GetValue(HeaderTypeProperty); }
        set { SetValue(HeaderTypeProperty, value); }
    }

    }
}

转换器代码:

public class HeaderType1BoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return object.Equals(value, "1");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class HeaderType2BoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return object.Equals(value, "2");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在调用代码中:

<template:HeaderTemplate Header="Application" HeaderType="1" />

标签: xamarinxamarin.forms

解决方案


使用触发器是一种选择。

例如:您可以添加属性触发器来检查值HeaderType并相应地更新Content自定义控件中的(或布局)HeaderView

ContentView请注意,在这种情况下,我们不是StackLayout在假设一次只有一个布局/控件可见的情况下进行扩展的。

XAML

<ContentView 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:SampleApp" 
    x:Class="SampleApp.HeaderView">

    <ContentView.Triggers>

        <!-- if header type is 1, use header1 layout -->
        <Trigger TargetType="local:HeaderView" Property="HeaderType" Value="1">
            <Setter Property="Content">
                <Setter.Value>
                    <Label Text="Header1" />
                </Setter.Value>
            </Setter>
        </Trigger>

        <!-- if header type is 2, use header2 layout -->
        <Trigger TargetType="local:HeaderView" Property="HeaderType" Value="2">
            <Setter Property="Content">
                <Setter.Value>
                    <StackLayout>
                        <Label Text="Header2" />
                        <BoxView HeightRequest="1" BackgroundColor="Gray" />
                    </StackLayout>
                </Setter.Value>
            </Setter>
        </Trigger>

        <!-- you can add more layouts here if you need -->

    </ContentView.Triggers>

    <!-- add default content that can be displayed in case of no match -->
    <StackLayout>
        <Label Text="DefaultHeader" />
        <BoxView HeightRequest="1" BackgroundColor="Gray" />
    </StackLayout>    

</ContentView>

代码隐藏

public partial class HeaderView : ContentView
{
    public HeaderView()
    {
        InitializeComponent();

    }

    public static readonly BindableProperty HeaderTypeProperty =
        BindableProperty.Create(
            nameof(HeaderType), typeof(string), typeof(HeaderView),
            defaultValue: default(string));

    public string HeaderType
    {
        get { return (string)GetValue(HeaderTypeProperty); }
        set { SetValue(HeaderTypeProperty, value); }
    }
}

用法

<local:HeaderView HeaderType="1" />

推荐阅读