这是我到目前为止提出的方法。但是,似乎不是一个干净的解决方案。
有人对我如何提出一个更好的解决方案有什么建议吗?
<?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" />
答案 0 :(得分:1)
使用triggers是一种选择。
例如:您可以添加属性触发器以检查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" />
答案 1 :(得分:1)
我相信您正在寻找的是ControlTemplate,这是一个实现。
App.xaml
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="Header1Template">
<StackLayout>
<!-- code -->
</StackLayout>
</ControlTemplate>
<ControlTemplate x:Key="Header2Template">
<StackLayout>
<!-- code -->
</StackLayout>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
用法(这将header1设置为默认值,您可以选择二者之一)
<ContentView x:Name="contentView" ControlTemplate="{StaticResource Header1Template}">
现在,有许多方法可以更改标题,方法是将其定义为上面的默认代码,或者通过动作进行操作,该动作可以是按钮单击(如链接上给出的示例),也可以使用propertyChange事件(如果要依赖)选择标题的属性,如:
public int HeaderNumber { get; set; }
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == "HeaderNumber")
{
contentView.ControlTemplate = (HeaderNumber == 1) ? Header1Template : Header2Template;
}
}
请注意,我从未实现过ControlTemplate,但我认为这可以解决您的问题。