-
Notifications
You must be signed in to change notification settings - Fork 12
Sheet
A sheet appears as a card that partially covers the page and can be dragged in a vertical direction to show more content. The page's content is visible behind the sheet to help people to remember the context they suspended when they opened the sheet.
A sheet needs to live inside of a ModalityLayout
. The ModalityLayout
will provide an overlay that is disabled until the modal component closes. It will also add the possibility of tapping the overlay to close the modal component. The ModalityLayout
should be placed at the root of your page for the best user experience.
In your XAML page, add the following:
<Contentpage
...
xmlns:dxui="http://dips.xamarin.ui.com"
... >
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior>
<!-- sheet content goes here -->
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
👉 All pictures and GIFs are taken from a android simulator, but the look and feel of this component is the same for android / ios devices.
👉 Samples can be found here
👉 A small demonstration of Sheet was visible at .Net Conf:2020
To open a sheet, set the IsOpen
property to True
.
👉 This is a bindable property and should be bound to a view model property that changes when people tap a view element inside of the page.
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True">
<!-- sheet content goes here -->
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
Content of the sheet can be set by setting the SheetContent
property, which is the default ContentProperty
of the behavior. This means that you can add the content directly inside of the SheetBehavior
tags.
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True">
<!-- sheet content goes here -->
<Label Text="This is the sheet content"/>
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
The sheet's alignment can be changed by setting the Alignment
property.
👉 Default is
Bottom
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True"
Alignment="Top" >
<!-- sheet content goes here -->
<Label Text="This is the sheet content"/>
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
The default behavior of the sheet is to take as much space as it needs when it opens. One exception to that is if a MinPosition
is set. The sheet will either take as much space as it needs, or set the position to a MinPosition
if the position from the content size is smaller than that.
Another exception is if the consumer of the API has set the Position
property. This property has to have values between 0.0 - 1.0 (0% - 100% of the screen).
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True"
Position="0.5"
MinPosition="0.4"
MaxPosition="0.7">
<!-- sheet content goes here -->
<Label Text="This is the sheet content"/>
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
👉 This property is a two-way binding, and the consumer can use this to get notified for changes to the sheet.
👉 Setting
MinPosition
/MaxPosition
will prevent people from dragging the sheet below / above the threshold. In this example the sheet is placed at 50% of the screen and people can not drag the sheet below 40% or above 70% of the screen.
The sheet can be dragged by setting the IsDraggable
to True
.
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True"
IsDraggable="True" >
<!-- sheet content goes here -->
<Label Text="This is the sheet content"/>
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
The content of the sheet might have some kind of view element that should close the sheet. This can be achieved by using our Modality.CloseOnClick
attached property on the view element.
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True">
<!-- sheet content goes here -->
<StackLayout>
<Label Text="This is the sheet content" />
<Button Text="Press to close"
dxui:Modality.CloseOnClick="True" />
</StackLayout>
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
👉 This attached property can be attached to any type of
Xamarin.Forms.View
element.
The sheet automatically closes when people drag it below 0.05 %
of the ModalityLayout
.
If you want to prevent this, you can set MinPosition
to a percentage that is bigger than 0.05
.
The background of the sheet's content, header and the drag-handle's can be changed:
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True"
IsDraggable="True"
HeaderColor="#323E40"
ContentColor="#323E40"
HandleColor="#D94D1A">
<!-- sheet content goes here -->
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
The content of the sheet might need it's own BindingContext
. This is natural when working with the MVVM pattern.
In the following examples, we have added a SheetPageViewModel
that should provide an instance of InsideSheetViewModel
.
-
SheetPageViewModel
should be theBindingContext
of the entire page. -
InsideSheetViewModel
should be theBindingContext
of the sheet's content.
xaml:
<ContentPage>
<ContentPage.BindingContext>
<local:SheetPageViewModel />
</ContentPage.BindingContext>
<dxui:ModalityLayout>
<dxui:ModalityLayout.Behaviors>
<dxui:SheetBehavior IsOpen="True"
IsDraggable="True"
BindingContextFactory="{Binding SheetViewModelFactory}">
<!-- sheet content goes here -->
<Label Text="{Binding Title}" /> <!-- "Sheet Title" is the value here -->
</dxui:SheetBehavior>
</dxui:ModalityLayout.Behaviors>
<!-- page content goes here -->
</dxui:ModalityLayout>
</ContentPage>
SheetPageViewModel
:
public class SheetPageViewModel : INotifyPropertyChanged
{
public Func<object> SheetViewModelFactory => () => new InsideSheetViewModel();
public event PropertyChangedEventHandler PropertyChanged;
}
InsideSheetViewModel
:
public class InsideSheetViewModel : INotifyPropertyChanged
{
public string Title => "Sheet Title";
public event PropertyChangedEventHandler PropertyChanged;
}
Here is a small demonstration of the sheet running on an iOS simulator with our samples code.
👉 The demonstration page can be outdated.
Property | Explanation | Remarks | default value |
---|---|---|---|
Alignment |
Determines the position of the sheet when it appears. | Bottom |
|
VerticalContentAlignment |
Determines how the content of the sheet should align. | Fit |
|
SheetContent |
The content of the sheet. |
BindingContextFactory to set the binding context when the sheet opens |
null |
BindingContextFactory |
Used to set the binding context of the content of the sheet when the sheet opens. | If this is not set, the BindingContext of the ModalityLayout will be used. |
null |
ContentColor |
Determines the background color of the content part of the sheet. | Color.White |
|
HeaderColor |
etermines the background color of the header part of the sheet. | Color.White |
|
HandleColor |
Determines the color of the handle in the sheet. | ColorPalette.QuinaryAir |
|
HasShadow |
Determines if the sheet should have shadow. | This only works for iOS. | false |
IsDraggable |
Determines if the sheet should be drag-able or not. | false |
|
IsOpen |
Determines if the sheet should be visible or not. | false |
|
MaxPosition |
Determines the maximum position of the sheet when it is visible. | This will affect the size of the sheet if Position is set to 0.0 . This will affect the people that are dragging the sheet. The value have to be between 0.0 and 1.0 (percentage of the screen) |
1.0 |
MinPosition |
Determines the minimum position of the sheet when it is visible. | This will affect the size of the sheet if Position is set to 0.0 . This will affect the people that are dragging the sheet. The value have to be between 0.0 and 1.0 (percentage of the screen) |
0.1 |
OnOpen |
Event that gets raised when the sheet has completed it's animation and is open. | ||
OnOpenCommand |
Command that executes when the sheet has completed it's animation and is open | null | |
OnOpenCommandParameter |
The parameter to pass to theOnOpenCommand
|
null | |
OnClose |
Event that gets raised when the sheet has completed it's animation and is closed. | ||
OnCloseCommand |
TCommand that executes when the sheet has completed it's animation and is closed | null | |
OnCloseCommandParameter |
The parameter to pass to the OnCloseCommand
|
null | |
OnBeforeClose |
Event that gets raised before the sheet start it's animation when closing | ||
OnBeforeCloseCommand |
Command that execute before the sheet start it's animation when closing. | null | |
OnBeforeCloseCommandParameter |
The parameter to pass to OnBeforeCloseCommand
|
null | |
OnBeforeOpen |
Event that gets raised when the sheet is about to start it's animation to open. | ||
OnBeforeOpenCommand |
Command that execute when the sheet is about to start it's animation to open. | null | |
OnBeforeOpenCommandParameter |
Parameter to pass to OnBeforeOpenCommand
|
null | |
OnBeforeOpenCommandParameter |
Parameter to pass to OnBeforeOpenCommand
|
null | |
OnPositionChanged |
Event that gets raised when the sheet has changed it's position. | null | |
OnPositionChangedCommand |
A command that executes when the position of the sheet changes. | The command parameter will be the new positional value, same as Position
|
null |
CloseOnOverlayTapped |
Determines if the sheet should close when the overlay is tapped. | true | |
ShouldRememberPosition |
Determines if the sheet should remember the position it had when it is closed. | false |
- ContentControl
- DataTemplateSelectors
- Date- and TimePicker
- Modality
- Contextual Menus
- RadioButton
- TrendGraph
- Tag
- Toast