Documentation

Intro

Table of Contents

Shell XAML

Shell.xaml is the main entry point of the app and defines the data model and navigation.

<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://schemas.snapworx.at/appshell/2016/xaml"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Sample">  
  <Shell.Entities>
    <!--Definition of data source entities used in lists and forms-->
  </Shell.Entities>
  <Shell.Tiles>
    <!--Optional definition of map tiles used as background or map overlay-->
  </Shell.Tiles>
  <Shell.Views>
    <!--Definition of UI views / navigation targets-->
  </Shell.Views>
</Shell>

Entities

<Shell.Entities>
  <Entity Id="Table1" Key="id" SyncType="Automatic" Table="table1" RevisionField="lastupdatetime">
    <Field Name="id" Type="Guid" IsRequired="True" />
    <Field Name="name" Type="String" MaxLength="256" />
    <Field Name="geometry" Type="Geometry" />
    <Field Name="lastupdatetime" Type="DateTime" />
  </Entity>
</Shell.Entities>

Key field must be of type Guid if you want to create records offline

Entity

<Entity Id="" Title="" Table="" Key="" SyncType="" RevisionField="">

Field

<Field Name="" Type="" IsRequired="" MinLength="" MaxLength="" EpsgCode="" 
       LazyLoading="" ForeignEntity="" DefaultValue="" />

Field Types

AutoIncrement, Timestamp and UnixTimestamp are automatically updated on modification of an entity.

Sync Types

Value Description
None Entity is only available online
Automatic Entity is synced automatically on each login
Automatic (with revision field) Entity is synced automatically on each login, but only changes which have a higher value in the revison field since last sync (diff sync)
Manual Entity will only be synced once. You can sync it manually in the Synchronization view

Validators

<Field>
  <RegexValidator Message="" Pattern="" />
  <MinValidator Message="" Minimum="" />
  <MaxValidator Message="" Maximum="" />
</Field>

Filters

<Entity.Filters>
  <Filter Id="" Sql="" IsDefault="" />
</Entity.Filters>

Triggers

<Entity.Triggers>
  <Trigger Id="" Method="" />
  <SqlTrigger Sql="" />
  <MailTrigger From="" To="" Subject="" Body="" />
  <UrlTrigger Url="" HttpMethod="" Headers="" Data="" />
  <UpdateFieldTrigger Field="" Value="" />
  <RemoveFieldTrigger Field="" />
</Entity.Triggers>

Id and Method attribute applies to all trigger types.

Trigger Methods

You can specify multiple methods separated with a comma

Tiles

Configuration of tile sources for map views (WMTS, WMS and TMS). Projection must be EPSG:3857.

<Shell.Tiles>
  <UrlTileOverlay Id="" TileWidth="" TileHeight="" MinimumZoomLevel="" MaximumZoomLevel="" Url="" />
</Shell.Tiles>

Views

List XAML

Defines a list configuration.

Name of your XAML file is the view name in Shell.xaml

<?xml version="1.0" encoding="utf-8" ?>
<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <List.ShellActions>
    <!--Definition of shell actions on the top right-->
  </List.ShellActions>    
  <List.RowActions>
    <!--Definition of actions for each list row-->
  </List.RowActions>
  <List.Sort>
    <!--Definition of default sorting-->
  </List.Sort>
  <!--Definition of various list cells-->
</List>

Shell Actions

<ShellAction Icon="" Type="" />

<NavigateShellAction Target="" />
<SearchShellAction Filter="" Placeholder="" />
<OpenUriShellAction Uri="" />
<FilterShellAction />

Shell Action Type

Row Actions

<NavigateRowAction Icon="" Target="" />
<ScriptRowAction Icon="" />
<OpenUriRowAction Uri="" />

Sort

<ListSort Name="" Order="" />

Sort Order

Cells

<Cell Name="" Title="" ShortTitle="" Width="" DisplaySize="" WordWrap="" />

<ListCell StringFormat="" ForeignField="" />
<DistanceListCell />
<MultiListCell>
  <!--List Cells-->
</MultiListCell>

Display Size

Word Wrap

Form XAML

Defines a form configuration.

Name of your XAML file is the view name in Shell.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Form.ShellActions>
    <!--Definition of shell actions on the top right-->
  </Form.ShellActions>    
  <Form.Scripts>
    <!--Definition of scripts-->
  </Form.Scripts>  
  <!--Definition of various form fields-->
</Form>

Shell Actions

<ShellAction Icon="" Type="" />

<SaveShellAction />
<DeleteShellAction />
<ScriptShellAction />
<PrevShellAction />
<NextShellAction />
<NavigateShellAction Target="" />
<OpenUriShellAction Uri="" />

Shell Action Type

Scripts

<StartupScript />
<ChangeScript Name="" Field="" />
<SharedScript />

Fields

<Field Name="" Title="" Placeholder="" Help="" IsVisible="" IsRequired=""
       IsEnabled="" DefaultValue="" />

<Entry />
<Editor />
<DatePicker />
<TimePicker />
<DateTimePicker />
<Distance />
<Picker KeyMember="" DisplayMember="" Items="" />
<Geometry />
<ImagePicker PreviewField="" SizeField="" MimeTypeField="" />
<FilePicker FileNameField="" SizeField="" MimeTypeField="" />
<AutoComplete Entity="" DisplayField="" />
<OptionsGroup MultiSelect="">
  <Option Value="" Title="" /> 
  <Option Field="" Title="" />
</OptionsGroup>
<Switch />
<Info />
<Table Entity="" RelationEntity="" Target="" RowCount="">
  <Table.RowActions>
  </Table.RowActions>
  <Table.Actions>
  </Table.Actions>
  <TableCell Name="" Title="" />
</Table>
<Group IsExpanded="" />
<TabGroup IsExpanded="">
  <FieldTab Name="" Title="">
    <FieldTab.Fields>      
    </FieldTab.Fields>
  </FieldTab>
</TabGroup>

Field Actions

<FieldAction Icon="" />

<NavigateFieldAction Target="" />
<ScriptFieldAction />
<MessageFieldAction Message="" Cancel="" />
<DateTimeNowFieldAction />
<GeometryFieldAction Target="" Edit="" GeometryType="" />
<DownloadImageFieldAction />
<PickImageFieldAction />
<TakeImageFieldAction />
<PickFileFieldAction IsText="" />
<ExecuteTriggerFieldAction Trigger="" />
<OpenUriFieldAction Uri="" />

Map XAML

Defines a map configuration.

Name of your XAML file is the view name in Shell.xaml

<?xml version="1.0" encoding="utf-8" ?>
<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.ShellActions>
    <!--Definition of shell actions on the top right-->
  </NativeMap.ShellActions>    
  <NativeMap.Layers>
    <!--Definition of layers-->
  </NativeMap.Layers>
</NativeMap>

Shell Actions

<ShellAction Icon="" Type="" />

<CurrentLocationAction />
<ToggleLayerAction />
<CaptureMarkerAction Target="" />
<NavigateSelectionAction />
<NavigateCarSelectionAction />
<CaptureDistanceAction />
<OpenUriShellAction Uri="" />
<CaptureCarDestinationAction />

Shell Action Type

Layers

<Layer Title="" IsActive="" />

<NativeLayer Type="" />
<TileLayer TileRef="" />

<VectorLayer Entity="" MinimumZoomLevel="" MaximumZoomLevel="" ZIndex="" Filter="">
  <FeatureInfo Title="" Detail="">
    <!--Shell Actions-->
  </FeatureInfo>
</VectorLayer>

<MarkerVectorLayer Icon="" SelectionIcon="" IconSize="" AnchorPoint="" />
<LineVectorLayer Color="" StrokeWidth="" SelectionColor="" IsDashed="" />
<PolygonVectorLayer Color="" FillColor="" StrokeWidth="" SelectionColor="" SelectionFillColor="" IsDashed="" />
<CircleVectorLayer Color="" FillColor="" StrokeWidth="" SelectionColor="" SelectionFillColor="" IsDashed="" Radius="" />

Native Layer Type

JavaScript API

General

message(message: string): void;
alert(message: string, accept: string, cancel: string, resultCallback: () => bool): void;
getUserName(): string;
getSessionKey(key: string): any;
setSessionKey(key: string, value: any): void;
removeSessionKey(key: string): void;
hasSessionKey(key: string): boolean;
getClipboardText(resultCallback: () => string): void;
setClipboardText(text: string): void;
syncEntity(name: string, resultCallback: () => void): void;
scanCode(resultCallback: () => string): void;

setVisible(name: string, visible: boolean): void;
isVisible(name: string): boolean;
show(name: string): void;
hide(name: string): void;

setEnabled(name: string, enabled: boolean): void;
isEnabled(name: string): boolean;
enable(name: string): void;
disable(name: string): void;

List

getValue(fieldName: string): any;
setValue(fieldName: string, value: any): void;

Form

getValue(fieldName: string): any;
setValue(fieldName: string, value: any): void;
copyValue(sourceFieldName: string, targetFieldName: string): void;
//Returns distance from current GPS position to geometry center in meters
getDistance(fieldName: string): number;
setDateNow(fieldName: string): void;
setGpsPosition(fieldName: string, accuracyFieldName?: string): void;

collapse(groupName: string): void;
expand(groupName: string): void;

setRequired(fieldName: string, required: boolean): void;
isRequired(fieldName: string): boolean;

isInsert(): boolean;
setValid(valid: boolean): void;
isValid(): boolean;

Scripts can be used in multiple ways

<!--As row action in a list-->
<List.RowActions>
  <ScriptRowAction>
    <ScriptRowAction.Script>
    </ScriptRowAction.Script>
  </ScriptRowAction>
</List.RowActions>

<!--After a selection in a list-->
<List.SelectionScript>
</List.SelectionScript>

<!--Before or after any action-->
<DeleteShellAction>
  <DeleteShellAction.BeforeScript>
  </DeleteShellAction.BeforeScript>
  <DeleteShellAction.AfterScript>
  </DeleteShellAction.AfterScript>
</DeleteShellAction>

<!--As field action in a form-->
<Entry Name="entry" Title="Entry">
  <ScriptFieldAction>
  </ScriptFieldAction>
</Entry>

<!--After loading a form-->
<Form.Scripts>
  <StartupScript>
  </StartupScript>
</Form.Scripts>

<!--After changing a field in a form-->
<Form.Scripts>
  <ChangeScript Field="FieldName" Name="OnFieldNameChanged">
  </ChangeScript>
</Form.Scripts>

<!--After a selection in a map-->
<NativeMap.SelectionScript>
</NativeMap.SelectionScript>

<!--After a selection in a map for a specific vector layer-->
<MarkerVectorLayer.SelectionScript>
</MarkerVectorLayer.SelectionScript>

Graphics

Icons

Icon Name Icon Name Icon Name Icon Name Icon Name
AppSelect AreaList Back Bell Chat
Checklist Compass DataSource Delete DeviceList
Distance Down Download Filter Flag
Gps Hamburger Help Home Info
Left LineList List Logging Logout
Map Message More New Password
PinList QRCode Request Right RightList
SatelliteMap Save Setting Start Stop
StreetMap Summary Synchronize Text TopoMap
Up Url User UserList Walk
Work World X

Actions

Icon Name Icon Name Icon Name Icon Name Icon Name
Alert Attachment Bicycle Bin Camera
Car Check Click Clock Delete
Edit EditArea EditLine EditPin Expand
Gps Helicopter Info Layer Map
Micro Minus More NewArea NewLine
NewPin Pause Pdf Phone Plus
Prev Question Refresh Save Search
Signature Start Stop View Walk
World

Map

Icon Name Icon Name Icon Name Icon Name Icon Name
Area Arrow Bicycle Car Delete
Edit End Helicopter Line Pin
Plus Start Walk

Samples

Shell

Apply a default filter to an entity

<Entity.Filters>
  <Filter Id="OpenTasks" Sql="endtime IS NULL" IsDefault="True" />
</Entity.Filters>

Filter an entity by user id

<Entity.Filters>
  <Filter Id="UserTasks" Sql="userid = @{System.UserId}" IsDefault="True" />
</Entity.Filters>

Add a regex validator to a field

<Field Name="name" Type="String" IsRequired="True">
  <RegexValidator Pattern="^[a-zA-Z0-9]+$" />
</Field>

Add a trigger to an entity which is executed before an insert or update and sets the current user id

<Entity.Triggers>
  <UpdateFieldTrigger Method="BeforeSave,BeforeUpdate" Field="userid" Value="@{System.UserId}" />
</Entity.Triggers>

Using a TMS tile source

<Shell.Tiles>
  <UrlTileOverlay Id="osm" TileWidth="256" TileHeight="256" MinimumZoomLevel="0" MaximumZoomLevel="20"
                  Url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />  
</Shell.Tiles>

Using a restful WMTS tile source

<Shell.Tiles>
  <UrlTileOverlay Id="wmts" TileWidth="512" TileHeight="512" MinimumZoomLevel="0" MaximumZoomLevel="20"
                  Url="https://maps.wien.gv.at/basemap/bmaphidpi/normal/google3857/{z}/{y}/{x}.jpeg" />
</Shell.Tiles>

Using a WMS tile source

<Shell.Tiles>
  <UrlTileOverlay Id="wms" TileWidth="512" TileHeight="512" MinimumZoomLevel="10" MaximumZoomLevel="20"
                  Url="https://data.wien.gv.at/daten/geo?version=1.3.0&amp;service=WMS&amp;request=GetMap&amp;crs=EPSG:4326&amp;bbox={bbox}&amp;width={width}&amp;height={height}&amp;layers=ogdwien:SPIELPLATZOGD&amp;styles=&amp;format=image/png&amp;transparent=true" />
</Shell.Tiles>

List

Show a field in a list

<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <ListCell Name="name" Title="Name" />
</List>

Show distance from current GPS position to geometry center

<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <DistanceListCell Name="geometry" Title="Distance" />
</List>

Show multiple fields in one cell

<MultiListCell Name="NameDescription" Title="Name / Description">
  <ListCell Name="name" />
  <ListCell Name="description" />
</MultiListCell>

Show date value with a specific format

<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <ListCell Name="begindate" Title="Begin Date" StringFormat="d" />
</List>
Format Description en-US de-DE
d Short date pattern. 6/15/2009 15.06.2009
D Long date pattern. Monday, June 15, 2009 Montag, 15. Juni 2009
f Full date/time pattern (short time). Monday, June 15, 2009 1:45 PM Montag, 15. Juni 2009 13:45
F Full date/time pattern (long time). Monday, June 15, 2009 1:45:30 PM Montag, 15. Juni 2009 13:45:30
g General date/time pattern (short time). 6/15/2009 1:45 PM 15.06.2009 13:45
G General date/time pattern (long time). 6/15/2009 1:45:30 PM 15.06.2009 13:45:30
M Month/day pattern. June 15 15. Juni
s Sortable date/time pattern. 2009-06-15T13:45:30 2009-06-15T13:45:30
t Short time pattern. 1:45 PM 13:45
T Long time pattern. 1:45:30 PM 13:45:30
u Universal sortable date/time pattern. 2009-06-15 13:45:30Z 2009-06-15 13:45:30Z
U Universal full date/time pattern. Monday, June 15, 2009 11:45:30 AM Montag, 15. Juni 2009 11:45:30
Y Year month pattern. June 2009 Juni 2009

Standard Date and Time Format Strings

Sort a list

<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <List.Sort>
    <ListSort Name="geometry" Order="Descending" />
  </List.Sort>
  <DistanceListCell Name="geometry" Title="Distance" />
</List>

Add a row action which navigates to a map view and centers the map to geometry center

<List xmlns="clr-namespace:AppShell;assembly=AppShell">
  <List.RowActions>
    <NavigateRowAction Icon="View" Target="NativeMapNavigation">
      <Parameter Name="Center" Value="@{geometry}" />
      <Parameter Name="ZoomLevel" Value="15" />
      <Parameter Name="SelectionId" Value="@{id}" />
    </NavigateRowAction>
  </List.RowActions>
</List>

Map value of a field to a display value in a list cell

<ListCell Name="DeviceType" Title="Device Type">
  <Mapping Key="0" Value="iOS" />
  <Mapping Key="1" Value="Android" />
  <Mapping Key="2" Value="Windows" />
</ListCell>

Show value of a foreign entity in a list cell

<ListCell Name="DataSource_Id" Title="DataSource" ForeignField="Name" />

<!--Make sure to define ForeignEntity in your Shell.xaml-->
<Field Name="DataSource_Id" Type="Guid" IsRequired="True" ForeignEntity="DataSource" />

Enable search in a list

<List.ShellActions>
  <SearchShellAction Filter="NameSearch" Placeholder="Your search hint" />
</List.ShellActions>

<!--Shell.xaml-->
<Entity.Filters>
  <Filter Id="NameSearch" Sql="name LIKE @{NameSearch}" />	
</Entity.Filters>

Form

Picker with static values

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Picker Name="color" Title="Color" KeyMember="Key" DisplayMember="Value"
          Items="{KeyValueList Red/Green/Blue}" />
</Form>

Picker with static keys and values

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Picker Name="country" Title="Country" KeyMember="Key" DisplayMember="Value"
          Items="{KeyValueList at-Austria/de-Germany/us-United States}" />
</Form>

Picker with values from an entity

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Picker Name="task_id" Title="Task" KeyMember="id" DisplayMember="name"
          Items="{Entity Tasks}" />
</Form>

Picker with values from an entity and a filter applied

<Entity Id="Tasks" Table="tasks" Key="id" SyncType="Automatic">
  <Entity.Filters>
    <Filter Id="OpenTasks" Sql="enddate IS NULL" />
  </Entity.Filters>
  ...
</Entity>

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Picker Name="task_id" Title="Task" KeyMember="id" DisplayMember="name"
          Items="{Entity Tasks, Filter=OpenTasks}" />
</Form>

Picker with values filtered based on another picker

<Entity Id="Countries" Table="countries" Key="id" SyncType="Automatic">	
  <Field Name="id" Type="Guid" IsRequired="True" />
  <Field Name="name" Type="String" IsRequired="True" />
</Entity>
<Entity Id="Cities" Table="cities" Key="id" SyncType="Automatic">
  <Entity.Filters>
    <Filter Id="CountryFilter" Sql="country_id = @{country_id}" />
  </Entity.Filters>
  <Field Name="id" Type="Guid" IsRequired="True" />
  <Field Name="country_id" Type="Guid" IsRequired="True" />
  <Field Name="name" Type="String" IsRequired="True" />
</Entity>

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Picker Name="country_id" Title="Country" KeyMember="id" DisplayMember="name"
          Items="{Entity Countries}" />
  <Picker Name="city_id" Title="City" KeyMember="id" DisplayMember="name" 
          Items="{Entity Cities, Filter=CountryFilter}" />
</Form>

DateTimePicker with a field action to set current date and time

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <DateTimePicker Name="begin" Title="Begin">
    <DateTimeNowFieldAction />
  </DateTimePicker>
</Form>

Using a script field action to set a field value

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Entry Name="scriptfield" Title="Script Field">
    <ScriptFieldAction Icon="Alert">
      Context.setValue('scriptfield', 'Test');
    </ScriptFieldAction>
  </Entry>
</Form>

Validate if a user is near an object before saving it

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Form.ShellActions>
    <SaveShellAction>
      <SaveShellAction.BeforeScript>
        var distance = Context.getDistance('geometry');
        if (!distance || distance &gt; 100) {
          Context.setError('geometry', 'Distance must be &lt; 100m to the venue');
          Context.setValid(false);
        }
      </SaveShellAction.BeforeScript>
    </SaveShellAction>
  </Form.ShellActions>
</Form>

Add an image picker to your form

<ImagePicker Name="image" Title="Image" PreviewField="previewimage" SizeField="imagesize" MimeTypeField="imagemimetype">
  <DownloadImageFieldAction />
  <PickImageFieldAction />
  <TakeImageFieldAction />
</ImagePicker>

PreviewField (optional field to store a thumbnail)
SizeField (optional field to store size of captured image)
MimeTypeField (optional field to store mime type of captured image)

Add support for paging to your form

<Form xmlns="clr-namespace:AppShell;assembly=AppShell">
  <Form.ShellActions>
    <PrevShellAction />
    <NextShellAction />
  </Form.ShellActions>
</Form>

Add an options group with a single selection

<OptionsGroup Name="Color" Title="Choose a color">
  <Option Value="red" Title="Red" />
  <Option Value="green" Title="Green" />
  <Option Value="blue" Title="Blue" />
</OptionsGroup>

Add an options group with multiple selections allowed separated by a comma

<OptionsGroup Name="Color" Title="Choose colors" MultiSelect="True">
  <Option Value="red" Title="Red" />
  <Option Value="green" Title="Green" />
  <Option Value="blue" Title="Blue" />
</OptionsGroup>

Add an options group with multiple selections allowed saved into multiple boolean fields

<OptionsGroup Title="Choose colors">
  <Option Field="red" Title="Red" />
  <Option Field="green" Title="Green" />
  <Option Field="blue" Title="Blue" />
</OptionsGroup>

Group fields in a form

<Group Name="History" Title="History">
  <Entry Name="CreatedBy" Title="Created By" IsEnabled="False" />
  <DateTimePicker Name="CreationTime" Title="Creation Time" IsEnabled="False" />
  <Entry Name="UpdatedBy" Title="Update By" IsEnabled="False" />
  <DateTimePicker Name="LastUpdateTime" Title="Update Time" IsEnabled="False" />
</Group>

Show fields in different tab groups

<TabGroup Name="Tabs" Title="Tabs" IsExpanded="True">
  <FieldTab Name="Tab1" Title="Tab 1">
    <FieldTab.Fields>
      <Entry Name="Entry1" Title="Entry 1" />
    </FieldTab.Fields>
  </FieldTab>
  <FieldTab Name="Tab2" Title="Tab 2">
    <FieldTab.Fields>
      <Entry Name="Entry2" Title="Entry 2" />
    </FieldTab.Fields>
  </FieldTab>
  <FieldTab Name="Tab3" Title="Tab 3">
    <FieldTab.Fields>
      <Entry Name="Entry3" Title="Entry 3" />
    </FieldTab.Fields>
  </FieldTab>
</TabGroup>

Capture a point geometry

<Geometry Name="geometry" Title="Geometry">
  <GeometryFieldAction Icon="EditPin" Target="NativeMap" Edit="True" />
</Geometry>

Capture a line geometry

<Geometry Name="geometry" Title="Geometry">
  <GeometryFieldAction Icon="EditLine" GeometryType="LineString" Target="NativeMap" Edit="True" />
</Geometry>

Capture a polygon geometry

<Geometry Name="geometry" Title="Geometry">
  <GeometryFieldAction Icon="EditArea" GeometryType="Polygon" Target="NativeMap" Edit="True" />
</Geometry>

Map

Map with native roads and satellite layer

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <NativeLayer Type="Roads" />
    <NativeLayer Type="Satellite" />    
  </NativeMap.Layers>
</NativeMap>

Reference a tile layer from Shell.xaml

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <TileLayer TileRef="basemap" />
  </NativeMap.Layers>
</NativeMap>

Add a marker vector layer with one of the embedded map icons

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <MarkerVectorLayer Entity="Wifis" MinimumZoomLevel="5" MaximumZoomLevel="20" Icon="Map.Pin.png" />
  </NativeMap.Layers>
</NativeMap>

Add a marker vector layer with an icon you deliver within the shell folder In this example a folder Icons with a file MyIcon.png inside is expected in the shell folder. You must also include MyIcon@2x.png, MyIcon@3x.png, MyIcon@4x.png for high DPI devices.

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <MarkerVectorLayer Entity="Wifis" MinimumZoomLevel="5" MaximumZoomLevel="20" Icon="Icons.MyIcon.png" />
  </NativeMap.Layers>
</NativeMap>

Add a marker vector layer with an icon depending on a field

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <MarkerVectorLayer Entity="Wifis" MinimumZoomLevel="5" MaximumZoomLevel="20" Icon="wifitype" />
  </NativeMap.Layers>
</NativeMap>

Add a marker vector layer with a filter applied

<Entity.Filters>
  <Filter Id="FreeWifiFilter" Sql="isfree = 1" />
</Entity.Filters>

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <MarkerVectorLayer Entity="Wifis" MinimumZoomLevel="5" MaximumZoomLevel="20" Icon="Map.Pin.png" Filter="FreeWifiFilter" />
  </NativeMap.Layers>
</NativeMap>

Show feature info on selection of a marker

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <MarkerVectorLayer Entity="Wifis" MinimumZoomLevel="5" MaximumZoomLevel="20" Icon="Map.Pin.png">
      <FeatureInfo Title="@{id}" Detail="Address: @{address}">
        <NavigateShellAction Icon="Edit" Target="TaskForm">
          <Parameter Name="Id" Value="@{id}" />
        </NavigateShellAction>
      </FeatureInfo>
    </MarkerVectorLayer>
  </NativeMap.Layers>
</NativeMap>

Add a line vector layer

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <LineVectorLayer Entity="Street" Color="#FF0000" SelectionColor="#00FF00" StrokeWidth="5" />
  </NativeMap.Layers>
</NativeMap>

Add a polygon vector layer

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.Layers>
    <PolygonVectorLayer Entity="Boundary" Color="#FF0000" FillColor="#88FF0000"
                        SelectionColor="#00FF00" SelectionFillColor="#8800FF00" />
  </NativeMap.Layers>
</NativeMap>

Capture a point geometry

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.ShellActions>
    <GeometryShellAction Entity="PointEntity" Target="PointForm" />
  </NativeMap.ShellActions>
</NativeMap>

Capture a line geometry

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.ShellActions>
    <GeometryShellAction Entity="LineEntity" GeometryType="LineString" Target="LineForm" />
  </NativeMap.ShellActions>
</NativeMap>

Capture a polygon geometry

<NativeMap xmlns="clr-namespace:AppShell;assembly=AppShell">
  <NativeMap.ShellActions>
    <GeometryShellAction Entity="PolygonEntity" GeometryType="Polygon" Target="PolygonForm" />
  </NativeMap.ShellActions>
</NativeMap>