I am using Xamarin.Forms and I have 2 pages, one is a List View, the other is a just a view I am using as a filter for the List View. I am currently using Navigation.PushAsync
to display this page, my question is, is there away to present it like a side menu? I know there is Master Detail View which I am already using for the main menu and I dont think I can have 2 Master Details in my app, I tried that approach but it adds an additional navigation.
Here is my code.
public partial class PatientsPage : ContentPage
{
public PatientsPage()
{
InitializeComponent();
ToolbarItems.Add(new ToolbarItem("Filter", "filter.png", () => { openFilter(); }));
}
public async void openFilter()
{
await Navigation.PushAsync(new PatientFiltersPage());
}
}
UPDATE
Is there away to have 2 details in 1 master to accomplish this? I really don't want to use a 3rd party library.
I personally do not know of
any way to have 2 details in 1 master
According to the documentation:
The Xamarin.Forms MasterDetailPage is a page that manages two related pages of information – a master page that presents items, and a detail page that presents details about items on the master page.
So in theory only one Detail page is allowed per Master page (although the detail page can be a NavigationPage itself).
But if you are flexible about how to approach your problem, i would suggest using an overlay with AbsoluteLayout
.
As an example, look at the image below, where i have a view over the main CollectionView
that can be shown or hidden by tapping on the "Filter" button:
Of course you can get as creative as you want, and make the view appear sliding from below, or from the side, or fading in: there is a robust support for animations in Xamarin.Forms. Also the view can be scrollable so that if you have a variety of filters you do not cover the whole CollectionView
with the Filter.
If that kind of solution is tolerable, you can achieve it as follows:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FilterDetail.StartPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Filter"
Clicked="ToolbarItem_Clicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<AbsoluteLayout>
<CollectionView x:Name="listView" AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Margin="15">
<Label Text="{Binding .}"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ContentView x:Name="FilterOverlay"
IsVisible="True" VerticalOptions="End"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent">
<Frame CornerRadius="10"
Margin="10"
HorizontalOptions="FillAndExpand" InputTransparent="False">
<StackLayout Padding="0">
<Label x:Name="FilterText"
Text="Filter Options"
FontSize="Medium"
TextColor="Black"/>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 1"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 2"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 3"/>
<Switch IsToggled="False" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 4"/>
<Switch IsToggled="True" />
</StackLayout>
<Button Text="Apply"
HeightRequest="30"
Padding="0"
BackgroundColor="Accent"/>
</StackLayout>
</Frame>
</ContentView>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FilterDetail
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StartPage : ContentPage
{
public StartPage()
{
InitializeComponent();
var items = new List<String>();
for (int i = 0; i < 1000; i++)
items.Add($"Item {i}");
listView.SetBinding(CollectionView.ItemsSourceProperty, new Binding() { Source = items, Path = "." });
}
private void ToolbarItem_Clicked(object sender, EventArgs e)
{
FilterOverlay.IsVisible = !FilterOverlay.IsVisible;
}
}
}
In order to simulate a second Master/Menu we can simply modify our solution presented above in order to expand our overlay vertically and add some animation so that instead of simply appear and disappear, the overlay hides to the right.
Let's see how this is done:
Add an overlay that covers the whole screen except from a margin on the left so that it looks like a Master Menu.
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"
x:Class="FilterDetail.StartPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Filter"
Clicked="ToolbarItem_Clicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<AbsoluteLayout>
<CollectionView x:Name="listView" AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Margin="15">
<Label Text="{Binding .}"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ContentView x:Name="FilterOverlay"
IsVisible="True"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent">
<Frame CornerRadius="10"
Margin="100,10,0,10"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
InputTransparent="False">
<StackLayout Padding="0">
<Label x:Name="FilterText"
Text="Filter Options"
FontSize="Medium"
TextColor="Black"/>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 1"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 2"/>
<Switch IsToggled="True" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 3"/>
<Switch IsToggled="False" />
</StackLayout>
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Label Text="Filter key 4"/>
<Switch IsToggled="True" />
</StackLayout>
<Button Text="Apply"
HeightRequest="30"
Padding="0"
BackgroundColor="Accent"
VerticalOptions="EndAndExpand"/>
</StackLayout>
</Frame>
</ContentView>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
Next, add some animation to ToolbarItem_Clicked
so that on tapping the Filter toolbar item, the overlay
hides to the right
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FilterDetail
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StartPage : ContentPage
{
public StartPage()
{
InitializeComponent();
var items = new List<String>();
for (int i = 0; i < 1000; i++)
items.Add($"Item {i}");
listView.SetBinding(CollectionView.ItemsSourceProperty, new Binding() { Source = items, Path = "." });
}
private async void ToolbarItem_Clicked(object sender, EventArgs e)
{
if (FilterOverlay.IsVisible)
{
// If overlay is visible, slide it to the right, and set as invisible.
await FilterOverlay.TranslateTo(this.Width-100, FilterOverlay.Y);
FilterOverlay.IsVisible = false;
}
else
{
// If overlay is invisible, make it visible and slide to the left.
FilterOverlay.IsVisible = true;
await FilterOverlay.TranslateTo(0, FilterOverlay.Y);
}
}
}
}
And that's it. The result looks like this:
Of course this is only a sample, and a bit of extra work on the overlay and on the animation can give you amazing results. Enjoy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With