基于Enum的XAML - Xamarin表格

时间:2017-03-06 05:56:49

标签: 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>

所以,例如,我想在订单状态为“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>-->

当订单“完成”时VS以下:

<!-- 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);
    }
}

2 个答案:

答案 0 :(得分:3)

因此,您希望根据视图模型中枚举的值显示部分UI?

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

  1. 将所有可能的值放入容器(GridStackLayoutAbsoluteLayout并使用转换器将其IsVisible属性绑定到枚举您的枚举值为truefalse
  2. 1。相同,但使用DataTrigger,无需任何转换器。这需要将Order枚举移出类,因为Xaml不能引用嵌套类型,并定义自定义xmlns(&#34; yourNs&#34;在以下示例中):< / LI>
    <!-- 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视图,并根据枚举值,将正确的实例设置为视图内容,使用后面的代码或DataTemplateSelector如果您坚持为所有内容使用Xaml。 / LI>

答案 1 :(得分:0)

我认为您尝试展示的enum是:

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

enumDropoffContact。如果我错了,请纠正我。

在这种情况下,Label会显示&#34;显示&#34;,因为它是string值的enum表示形式(相当于你&# 39; d与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}}" .../>