簡體   English   中英

基於枚舉的XAML-Xamarin表單

[英]XAML Based on Enum - 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>

因此,例如,當訂單狀態為“ 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>-->

當訂單“完成”時,與以下內容進行比較:

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

這是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);
    }
}

因此,您是否要根據視圖模型中枚舉的值顯示UI的各個部分?

有多種方法可以執行此操作,以下是幾種方法:

  1. 將所有可能的值放入容器( GridStackLayoutAbsoluteLayout然后使用轉換器將其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>
  1. 如果您有多個狀態,並且每個視圖都很復雜,則1.2.會生成一個巨大的Xaml,即使某些部分不可見,Xaml仍會被解析並創建對等對象。 最好的選擇可能是為每種情況定義一個Xaml視圖,並根據枚舉值將正確的實例設置為視圖內容,如果您堅持要使用Xaml,請使用后面的代碼或DataTemplateSelector

我假設您要顯示的enum是:

<Label Text="{Binding CurrentOrder.DropoffContact.Display}" .../>

enumDropoffContact 如果我錯了,請糾正我。

在這種情況下, Label將顯示“ Display”,因為它是enum值的string表示形式(等同於ToString() )。

如果要在Binding自定義為枚舉值顯示的文本,則可以使用轉換器,例如,如下所示:

public class MyEnumConverter : IValueConverter
{
    public object ConvertTo (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (!(value is DropoffContact))
            return value;
        switch (DropoffContact)value) {
        case DropoffContact.Display:
            return "Some string representation"
        default:
            return value;
        }
    }

    public void ConvertFrom (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        thrown new NotImplementedException();
    }
}

將該轉換器作為資源添加到您的Xaml頁,並在綁定中使用它:

<Label Text="{Binding CurrentOrder.DropoffContact.Display, Converter={StaticResource myResourceKey}}" .../>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM