基于枚举的XAML-Xamarin表单

Edi*_* W. 2 c# xaml xamarin xamarin.forms

我有一个作为枚举的订单状态属性,并且我想根据枚举值更改显示的XAML。

那可能吗?

这是我正在使用的所有布局的XAML(有些注释掉了):

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
    x:Class="Divco.OrderPage"
    Title="Order">
<ContentPage.BindingContext>
</ContentPage.BindingContext>
<ContentPage.Content>
    <!-- Basic stack layout used in all order views -->
    <StackLayout>
        <!--<StackLayout.Style>-->
            <!-- Needs Driver -->
            <!--<StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="150"
                    x:Name="WaitingMap"
                    IsShowingUser="false"
                    MapType="Street" />
            </StackLayout>
            <StackLayout Padding="20, 0, 20, 0">
                <Label Text="{Binding CurrentOrder.Description}" LineBreakMode="WordWrap" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Pickup" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Dropoff" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Button Text="Navigate!" 
                        BackgroundColor="Fuschia" 
                        TextColor="White" 
                        Font="Bold,20"
                        Grid.Row="0" Grid.Column="1" />
            </StackLayout>-->

            <!-- Waiting Driver -->
            <!--<StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="200"
                    x:Name="WaitingMap"
                    IsShowingUser="true"
                    MapType="Street" />
            </StackLayout>
            <StackLayout VerticalOptions="CenterAndExpand" Padding="20, 0, 20, 0" >
                <Label Text="Pickup" TextColor="Fuchsia" Font="Bold" />
                <Label Text="{Binding CurrentOrder.PickupContact.Display}"/>
                <Label Text="{Binding CurrentOrder.PickupAddress.Display}"/>
                <Label Text="{Binding CurrentOrder.PickupTimeFormatted}"/>
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Grid>
                    <Grid.RowDefinitions>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Button Text="Navigate" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="0"/>
                    <Button Text="Call" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="1"/>
                </Grid>
                <Button Text="I'm here!" 
                            BackgroundColor="Fuschia" 
                            TextColor="White" 
                            Font="Bold,20" />
            </StackLayout>-->

            <!-- Intransit -->
            <!--<StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="200"
                    x:Name="TransitMap"
                    IsShowingUser="true"
                    MapType="Street" />
            </StackLayout>
            <StackLayout VerticalOptions="CenterAndExpand" Padding="20, 0, 20, 0" >
                <Label Text="Dropoff" TextColor="Fuchsia" Font="Bold" />
                <Label Text="{Binding CurrentOrder.DropoffContact.Display}"/>
                <Label Text="{Binding CurrentOrder.DropoffAddress.Display}"/>
                <Label Text="{Binding CurrentOrder.DropoffTimeFormatted}"/>
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Grid>
                    <Grid.RowDefinitions>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Button Text="Navigate" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="0"/>
                    <Button Text="Call" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="1"/>
                </Grid>
                <Button Text="I'm here!" 
                            BackgroundColor="Fuschia" 
                            TextColor="White" 
                            Font="Bold,20" />
            </StackLayout>-->

            <!-- Needs Signature -->
            <!--<StackLayout VerticalOptions="CenterAndExpand" Padding="20, 20, 20, 20">
                <Label Text="In order to verify the identity of the signature, please take a photo of the recipient's ID." HorizontalTextAlignment="Center"/> 
                <Button Text="Take Picture"
                    BackgroundColor="Gray" 
                    TextColor="White" 
                    Font="Bold,20"/>
                <Button Text="Sign" 
                    BackgroundColor="Fuschia" 
                    TextColor="White" 
                    Font="Bold,20" IsEnabled="false"/>
            </StackLayout>-->

            <!-- Complete! -->
            <StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="150"
                    x:Name="WaitingMap"
                    IsShowingUser="false"
                    MapType="Street" />
            </StackLayout>
            <StackLayout Padding="20, 0, 20, 0">
                <Label Text="{Binding CurrentOrder.Description}" LineBreakMode="WordWrap" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Pickup" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Dropoff" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Label Text="This order is complete! Great work!" HorizontalTextAlignment="Center" TextColor="Fuchsia" Font="Bold"/>
            </StackLayout>
        <!--</StackLayout.Style>-->
    </StackLayout>
</ContentPage.Content>
Run Code Online (Sandbox Code Playgroud)

因此,例如,当订单状态为“ InTransit”时,我希望显示以下内容:

<!-- Intransit -->
            <!--<StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="200"
                    x:Name="TransitMap"
                    IsShowingUser="true"
                    MapType="Street" />
            </StackLayout>
            <StackLayout VerticalOptions="CenterAndExpand" Padding="20, 0, 20, 0" >
                <Label Text="Dropoff" TextColor="Fuchsia" Font="Bold" />
                <Label Text="{Binding CurrentOrder.DropoffContact.Display}"/>
                <Label Text="{Binding CurrentOrder.DropoffAddress.Display}"/>
                <Label Text="{Binding CurrentOrder.DropoffTimeFormatted}"/>
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Grid>
                    <Grid.RowDefinitions>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Button Text="Navigate" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="0"/>
                    <Button Text="Call" 
                            BackgroundColor="Gray" 
                            TextColor="White" 
                            Font="Bold" 
                            Grid.Row="0" Grid.Column="1"/>
                </Grid>
                <Button Text="I'm here!" 
                            BackgroundColor="Fuschia" 
                            TextColor="White" 
                            Font="Bold,20" />
            </StackLayout>-->
Run Code Online (Sandbox Code Playgroud)

当订单“完成”时,与以下内容进行比较:

<!-- Complete! -->
            <StackLayout>
                <maps:Map WidthRequest="320" HeightRequest="150"
                    x:Name="WaitingMap"
                    IsShowingUser="false"
                    MapType="Street" />
            </StackLayout>
            <StackLayout Padding="20, 0, 20, 0">
                <Label Text="{Binding CurrentOrder.Description}" LineBreakMode="WordWrap" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Pickup" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.PickupTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="Dropoff" TextColor="Fuchsia" Font="Bold,14" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffContact.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffAddress.Display}" Font="12" HorizontalTextAlignment="Center" />
                <Label Text="{Binding CurrentOrder.DropoffTimeFormatted}" Font="12" HorizontalTextAlignment="Center" />
            </StackLayout>
            <StackLayout VerticalOptions="EndAndExpand" Padding="20, 0, 20, 20">
                <Label Text="This order is complete! Great work!" HorizontalTextAlignment="Center" TextColor="Fuchsia" Font="Bold"/>
            </StackLayout>
Run Code Online (Sandbox Code Playgroud)

这是Order类供参考:

public class Order : INotifyPropertyChanged
{

    // event to handle changes in the order status 
    public event PropertyChangedEventHandler PropertyChanged;

    public enum Status { Preview, NeedsDriver, WaitingDriver, InTransit, NeedsSignature, Complete, Refunded }

    public string ID { get; set; }
    public string Description { get; set; }
    private Status _orderStatus;
    public Status OrderStatus { 
        get
        {
            return _orderStatus;
        }
        set
        {
            _orderStatus = value;
            // tell the view that the order status has changed 
            OnPropertyChanged("OrderStatus");
        }
    }
    public Contact PickupContact { get; set; }
    public Contact DropoffContact { get; set; }
    public Address PickupAddress { get; set; }
    public Address DropoffAddress { get; set; }
    public DateTime PickupTime { get; set; }
    public DateTime DropoffTime { get; set; }

    // Formatted Pickup and Dropoff Times
    public string PickupTimeFormatted
    {
        get { return PickupTime.ToString("g"); }
    }
    public string DropoffTimeFormatted
    {
        get { return DropoffTime.ToString("g"); }
    }

    public Order()
    {
    }

    // Handler to tell the view that the order status has changed 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    public override string ToString()
    {
        return string.Format("[Order: ID={0}, Description={1}, OrderStatus={2}, PickupContact={3}, DropoffContact={4}, PickupAddress={5}, DropoffAddress={6}, PickupTime={7}, DropoffTime={8}, PickupTimeFormatted={9}, DropoffTimeFormatted={10}]", ID, Description, OrderStatus, PickupContact, DropoffContact, PickupAddress, DropoffAddress, PickupTime, DropoffTime, PickupTimeFormatted, DropoffTimeFormatted);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*oix 5

因此,您是否要根据视图模型中枚举的值显示UI的各个部分?

有多种方法可以做到这一点,这里有几个:

  1. 将所有可能的值放入容器中(a Grid,a StackLayout,an,AbsoluteLayout然后IsVisible使用转换器将其属性绑定到枚举,该转换器会将您的枚举值转换为truefalse
  2. 1,但使用DataTrigger,无需任何转换器。这需要将Order枚举移出类,因为Xaml无法引用嵌套类型,并定义了一个自定义项xmlns(以下示例中为“ yourNs”):
<!-- InTransit -->
<StackLayout IsVisible="false"...>
  <StackLayout.Triggers>
    <DataTrigger TargetType="VisualElement" Binding="{Binding OrderStatus}" Value="{x:Static yourNs:Status.InTransit}">
      <Setter Property="IsVisible" Value="true" />
    </DataTrigger>
  </StackLayout.Triggers> 
  ...
</StackLayout>

<!-- Complete -->
<StackLayout IsVisible="false">
  <StackLayout.Triggers>
    <DataTrigger TargetType="VisualElement" Binding="{Binding OrderStatus}" Value="{x:Static yourNs:Status.Complete}">
      <Setter Property="IsVisible" Value="true" />
    </DataTrigger>
  </StackLayout.Triggers> 
  ...
</StackLayout>
Run Code Online (Sandbox Code Playgroud)
  1. 如果您有多个状态,并且每个视图都很复杂,则1.2.会生成一个巨大的Xaml,即使某些部分不可见,Xaml仍会被解析并创建对等对象。最好的办法可能是定义每种情况下XAML视图,并根据枚举值,设置正确的实例作为视图内容,使用后面的代码或者DataTemplateSelector,如果你坚持要去的XAML的一切。