关于基于Enum的c#:XAML-Xamarin表单

XAML Based on Enum - Xamarin Forms

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

有可能吗?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?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 "时,我希望显示以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!-- 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 "时,与以下内容相对:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 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类供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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的一部分?

有多种方法可以执行此操作,以下是几种方法:

  • 将所有可能的值放在一个容器中(一个Grid,一个StackLayout,一个AbsoluteLayout并使用转换器将其IsVisible属性绑定到枚举,该转换器会将您的枚举值转换为truefalse
  • 与1.相同,但使用DataTrigger,不需要任何转换器。这需要将Order枚举移出类,因为Xaml无法引用嵌套类型,并定义自定义xmlns(在以下示例中为" yourNs "):
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- 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.或2.会生成一个巨大的Xaml,即使某些部分不可见,Xaml仍会被解析并创建对等对象。最好的选择可能是为每种情况定义一个Xaml视图,并根据枚举值,使用后面的代码或DataTemplateSelector(如果您坚持将Xaml用于所有内容),将正确的实例设置为视图内容。

  • 我假设您要显示的enum是那些:

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

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

    在这种情况下,Label将显示" Display ",因为它是enum值(等同于ToString()的值)的string表示形式。铅>

    如果要自定义Binding中的枚举值显示的文本,可以使用不同的转换器,例如像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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页面,并在绑定中使用它:

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