Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have an order status property that is an enum, and I would like to change what XAML is displayed based on the enum value.
Is that possible?
Here is my XAML with all my layouts I've been working on (some commented out):
<?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.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.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>
So, for example I would like the following to display when the order status is "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.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 the following when the order is "complete":
<!-- 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>
Here is the Order class for reference:
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 {
return _orderStatus;
_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);
So you want to display parts of the UI depending on the value of an enum in your view model ?
There are multiple ways to do that, here are a few:
Put all the possible values in a container (a Grid
, a StackLayout
, an AbsoluteLayout
and bind their IsVisible
property to the enum using a converter that will convert your enum value to true
or false
Same as 1., but use a DataTrigger
, no need for any converter. This require moving the Order
enum out of the class as Xaml can't reference nested types, and defining a custom xmlns
("yourNs" in the following example):
<!-- 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>
If you have multiple status, and each view is complex, 1. or 2. will make a huge Xaml, and even though some parts are not visible, the Xaml is still parsed and the peer objects created. The best option is probably to define a Xaml view for each case, and depending on the enum value, set the right instance as the view content, using code behind or a DataTemplateSelector
if you insist of going Xaml for everything.
I assume the enum
s you're trying to display are those:
<Label Text="{Binding CurrentOrder.DropoffContact.Display}" .../>
and the enum
being DropoffContact
. If I'm wrong, please correct me.
In this case the Label
will display "Display", as it's the string
representation of the enum
value (equivalent to what you'd have with ToString()
).
If you want to customize the text displayed for an enum value in a Binding
, you can use a converter, differed e.g. like this:
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();
Add that converter to your Xaml page as Resource, and use it in the binding:
<Label Text="{Binding CurrentOrder.DropoffContact.Display, Converter={StaticResource myResourceKey}}" .../>
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.