Xamarin Forms iOS Navigation PushAsync shows Master Page Title on NavigationBar - xamarin

In my xamarin.forms project, Page1 is a detail page with master page title on navigatonbar. When i navigate to page3 from page1 viewmodel using PushAsync, page3 has got both master page title and navigationbar backbutton.When i navigate from page1 viewmodel to page2 from inside master page,page2 has only navbackbutton,no master title.When navigating from page2 viewmodel to page3, page3 also do not have master title,only navbackbutton.I do not have this issue on Android.How to hide Master page Title when navigate from page1 viewmodel to page3 on iOS?
page1 cs: vm method called for moving to page3
private async void Cart_Tapped(object sender, EventArgs e)
{
await img_cart.FadeTo(0.3, 500);
await img_cart.FadeTo(1, 500);
var vm = BindingContext as Main_page_vm;
vm?.Save_cart();
}
Navigating from page1 viewmodel to page3: Detail page to content page having issue
internal async void Save_cart()
{
if(Number.Equals(0))
{
App.Current.Properties["cartitems"] = purchaselist;
DependencyService.Get<IToast>().LongAlert("Empty cart !");
}
else
{
App.Current.Properties["cartitems"] = purchaselist;
List<tb_login> Login_list = App.Database.Get_user_id();
if (!Login_list.Count.Equals(0))
{
foreach (tb_login tb_Login in Login_list)
{
App.Current.Properties["user_id"] = tb_Login.user_id;
App.Current.Properties["username"] = tb_Login.user_name;
}
await Navigation.PushAsync(new Address_page2()); //to page3,now showing master
}
else
{
await Navigation.PushAsync(new LoginPage());
}
}
}
Page1 to page2: detail page to content page,No issues
private async void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as HomePageMenuItem;
if (item == null)
return;
if (item.Id == 0)
{
// Detail = new NavigationPage(new HomelyPage());
await Navigation.PushAsync(new HomelyPage());//to page2 has no master issues
}
IsPresented = false;
MasterPage.ListView.SelectedItem = null;
}
Page2 viewmodel to page3:content page to content page,No issues
public async void Save_cart()
{
if (Number.Equals(0))
{
App.Current.Properties["cartitems"] = purchaselist;
DependencyService.Get<IToast>().LongAlert("Empty cart !");
}
else
{
App.Current.Properties["cartitems"] = purchaselist;
List<tb_login> Login_list = App.Database.Get_user_id();
if (!Login_list.Count.Equals(0))
{
foreach (tb_login tb_Login in Login_list)
{
App.Current.Properties["user_id"] = tb_Login.user_id;
App.Current.Properties["username"] = tb_Login.user_name;
}
await Navigation.PushAsync(new Address_page2()); //to page3,also not showing master
}
else
{
await Navigation.PushAsync(new LoginPage());
}
}
}
page1 xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="OnRestaur.Views.Main_Page"
BackgroundColor="#f2f2f2"
NavigationPage.HasBackButton="False">
<NavigationPage.TitleView>
<StackLayout HorizontalOptions="EndAndExpand">
<Grid HorizontalOptions="EndAndExpand">
<Label Text="{Binding Number, Mode=TwoWay}" FontAttributes="Bold" HorizontalOptions="EndAndExpand" FontSize="Small" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" Margin="0,0,32,10" Style="{StaticResource Label_font}" TextColor="White">
</Label>
<Image Source="shoppingcart_white.png" x:Name="img_cart" HorizontalOptions="EndAndExpand" WidthRequest="60" HeightRequest="50" Margin="0,0,10,0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Cart_Tapped" />
</Image.GestureRecognizers>
</Image>
</Grid>
</StackLayout>
</NavigationPage.TitleView>
Page3 xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="OnRestaur.Views.Address_page2"
NavigationPage.HasBackButton="False"
Title=" ">
<NavigationPage.TitleView>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Margin="0" Spacing="0" Padding="0">
<Image Source="back_arrow.png" x:Name="img_cart" HorizontalOptions="StartAndExpand" WidthRequest="30" HeightRequest="30" Margin="0,0,0,0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Back_arrow_Tapped" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</NavigationPage.TitleView>
page2 xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Title="Home"
x:Class="OnRestaur.Views.HomelyPage"
xmlns:local="OnRestaur.Views;assembly=ContentView"
xmlns:custom="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
NavigationPage.HasBackButton="False">
<NavigationPage.TitleView>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Image Source="back_arrow.png" HorizontalOptions="StartAndExpand" WidthRequest="30" HeightRequest="30" Margin="0,0,0,0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Back_arrow_Tapped" />
</Image.GestureRecognizers>
</Image>
<Grid HorizontalOptions="EndAndExpand">
<Image Source="loc.png" x:Name="img_cart" HorizontalOptions="EndAndExpand" WidthRequest="20" HeightRequest="20" Margin="0,0,30,0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Loc_Tapped" />
</Image.GestureRecognizers>
</Image>
</Grid>
</StackLayout>
</NavigationPage.TitleView>

Change the Navigation to something like below and it should solve your issue:
Application.Current.MainPage.Navigation.PushAsync(new Address_page2());

Related

Gesture Recognizer go to detail

i have a page with Cards and once i tap on one i need to get detailed data. I have Gesture recognizer so i am able to navigate to he second page but with no details.
I have tried to add TapGesture in xaml but it didnt work.
This is my xaml
<grial:Repeater
Padding="0"
ItemsSource="{ Binding ListOfBestSellers }"
Orientation="Horizontal"
HeightRequest="200"
Spacing="0"
VerticalOptions="End"
ScrollBarVisibility="Never">
<grial:Repeater.ItemTemplate>
<DataTemplate >
<local:AvatArticleBrowserCardItemTemplate
Padding="10,0,5,5"
WidthRequest="150" >
</local:AvatArticleBrowserCardItemTemplate>
</DataTemplate>
</grial:Repeater.ItemTemplate>
</grial:Repeater>
and Template
<ContentView.Content>
<grial:CardView
VerticalOptions="Fill"
CornerRadius="5" x:Name="articleCard">
<grial:CardView.RowDefinitions>
<RowDefinition
Height="*" />
<RowDefinition
Height="Auto" />
</grial:CardView.RowDefinitions>
<!-- ARTICLE IMAGE -->
<ffimageloading:CachedImage
Grid.Row="0"
Margin="-14,0,-14,10"
Source="{ Binding BackgroundImage }"
Aspect="AspectFill" />
<Grid
Grid.Row="1"
VerticalOptions="End"
RowSpacing="10"
Padding="14,10">
<!-- TITLE -->
<Label
Grid.Row="0"
Text="{ Binding Title }"
FontSize="15"
Style="{ StaticResource LabelBoldStyle }"
TextColor="{ DynamicResource AccentColor }" />
<!-- CATEGORY -->
<Label
Grid.Row="1"
Text="{ Binding Section }"
FontSize="12"
VerticalOptions="Start" />
<!-- DATE -->
<Label
Grid.Row="1"
Text="{ Binding When }"
FontSize="12"
VerticalOptions="Start"
HorizontalOptions="End" />
</Grid>
</grial:CardView>
</ContentView.Content>
This is what i have
async void GoToCardDetail(object sender, EventArgs e)
{
if (LangUpLoggedUser.LoggedIn)
{
await Navigation.PushAsync(new MyArticle());
}
else
{
await Navigation.PushAsync(new Login());
}
}
private void CardDetail()
{
articleCard.GestureRecognizers.Clear();
TapGestureRecognizer gestureRecognizerArticleDetail = new TapGestureRecognizer();
gestureRecognizerArticleDetail.Tapped += GoToCardDetail;
articleCard.GestureRecognizers.Add(gestureRecognizerArticleDetail);
}
But its not giving me detailed data, on my list view from other page i have this
private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
#if !NAVIGATION
var selectedItem = ((ListView) sender).SelectedItem;
var articlePage = new MyArticle(selectedItem as ArticleDetailData);
await Navigation.PushAsync(articlePage);
#endif
}
my MyArticle const
public MyArticles()
{
InitializeComponent();
BindingContext = new MyArticlesListViewModel(null);
}
/// <summary>
///
/// </summary>
/// <param name="articles"></param>
/// <param name="categoryName"></param>
public MyArticles(List<Article> articles, string categoryName)
{
_categoryName = categoryName;
InitializeComponent();
BindingContext = new MyArticlesListViewModel(articles);
}
And that works perfectly can zou please help me how to achieve the same result?
you need to pass the selected item to MyArticle's constructor
var card = (CardView) sender;
var item = (ArticleDetailData)card.BindingContext;
await Navigation.PushAsync(new MyArticle(item));

Xamarin.Forms GestureRecognizers not working on Command

Code in the xaml page:
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<CollectionView ItemsSource="{Binding MeniElementi}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="10" WidthRequest="140" HeightRequest="140">
<Frame BackgroundColor="AliceBlue" WidthRequest="120" HeightRequest="120" HasShadow="True" CornerRadius="10" Padding="10" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" >
<StackLayout>
<Image Source="http://www.clker.com/cliparts/l/u/5/P/D/A/arrow-50x50-md.png" WidthRequest="70" HeightRequest="70" >
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding LoadElements}"
/>
</Image.GestureRecognizers>
</Image>
<Label Text="{Binding Title}" HeightRequest="50" WidthRequest="100" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
</StackLayout>
</Frame>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
Code in xaml.cs:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Menu: ContentPage
{
MenuViewModel viewModel = new MenuViewModel();
public Menu()
{
InitializeComponent();
BindingContext = viewModel;
}
}
Code in viewmodel.cs
public class MenuViewModel :BaseViewModel, INotifyPropertyChanged
{
public Command LoadElements { get; set; }
public ObservableCollection<Meni> MeniElementi { get; set; }
public MenuViewModel()
{
LoadElements= new Command(execute: async () => await ExecuteElements());
MeniElementi = new ObservableCollection<Meni>() {
new Meni(){Title="Transatcions" ,Picture="xxx"},
new Meni(){Title="Transatcions" ,Picture="xxx"},
};
}
async Task ExecuteElements()
{
try
{
await Application.Current.MainPage.Navigation.PushAsync(new InfoPage());
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
}
}
LoadElements Command not fired. Loading starting menu , showing menu elements just command not working to navigate to another page. Using Xamarin.Forms.Command. On other pages working normal with Command
You could reset the binding path of the tap . So that you can handle the logic in the same command .
in the ContentPage (which contains the CollectionView)
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="Page" //set the name of page
x:Class="xxx.xxxPage">
<TapGestureRecognizer Command="{Binding Source={x:Reference Page},Path=BindingContext.LoadElements}"
you need to call the command on the ViewModel of the Page for that you need to do this:-
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoadElements, Source={x:Reference Name=ThisPage}}" />
</Image.GestureRecognizers>
And put x:Name="ThisPage" in the ContentPage tag of the xaml at the top of the page.
Let me know if you face difficulties.

error in my Navigation. PushAsync (new DetailsPage (monkey))

I'm following the following example of carousel with the listview, more when I go to open Navigation.PushAsync the item in the listview is called only the first item, on all items clicked his name only the first item, a position error?
void Handle_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var monkey = ((ListView)sender).SelectedItem as Monkey;
if (monkey == null)
return;
Navigation.PushAsync(new DetailsPage(monkey));
}
https://blog.xamarin.com/flip-through-items-with-xamarin-forms-carouselview/
EDIT
MonkeysPage.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="Monkeys.Views.MonkeysPage"
xmlns:design="clr-namespace:Monkeys;assembly=Monkeys"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
BindingContext="{x:Static design:ViewModelLocator.MonkeysViewModel}"
x:Name="MonkeysPage"
Title="Traditional Monkeys">
<ContentPage.Content>
<ListView ItemsSource="{Binding MonkeysGrouped}"
ItemSelected="Handle_ItemSelected"
HasUnevenRows="true"
GroupShortNameBinding = "{Binding Key}"
IsGroupingEnabled = "true"
GroupDisplayBinding = "{Binding Key}">
<ListView.Header>
<cv:CarouselView x:Name="CarouselZoos" ItemsSource="{Binding Path=BindingContext.Zoos, Source={x:Reference MonkeysPage}}" HeightRequest="200">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.RowSpan="2" Aspect="AspectFill" Source="{Binding ImageUrl}"/>
<StackLayout Grid.Row="1" BackgroundColor="#80000000" Padding="12">
<Label TextColor="White" Text="{Binding Name}" FontSize="16" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</Grid>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<controls:CircleImage
BorderColor="Aqua"
BorderThickness="3"
HeightRequest="66"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
Aspect="AspectFill"
WidthRequest="66"
Grid.RowSpan="2"
Source="{Binding Image}"/>
<Label Grid.Column="1"
Text="{Binding Name}"
VerticalOptions="End"/>
<Label Grid.Column="1"
Grid.Row="1"
VerticalOptions="Start"
Text="{Binding Location}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MonkeysPage.xaml.cs
public MonkeysPage()
{
InitializeComponent();
BindingContext = new MonkeysViewModel();
}
async void Handle_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var monkey = e.SelectedItem as Monkey;
if (monkey == null)
return;
await Navigation.PushAsync(new DetailsPage(monkey)); // always await Navigations
((ListView)sender).SelectedItem = null;
}
DetailsPage.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="Monkeys.Views.DetailsPage"
xmlns:design="clr-namespace:Monkeys;assembly=Monkeys"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
BindingContext="{x:Static design:ViewModelLocator.DetailsViewModel}"
Title="{Binding Monkey.Name}">
<ContentPage.Content>
<ScrollView>
<StackLayout Padding="10">
<controls:CircleImage
BorderColor="Aqua"
BorderThickness="3"
HeightRequest="200"
WidthRequest="200"
HorizontalOptions="CenterAndExpand"
Aspect="AspectFill"
Source="{Binding Monkey.Image}"/>
<Label Text="{Binding Monkey.Name}" FontAttributes="Bold"/>
<Label Text="{Binding Monkey.Location}" FontSize="Micro"/>
<Label Text="{Binding Monkey.Details}" FontSize="Large"/>
</StackLayout>
</ScrollView>
</ContentPage.Content>
DetailsPage
public partial class DetailsPage : ContentPage
{
public DetailsPage(Monkey monkey)
{
InitializeComponent();
}
}
You're doing everything good except that you forgot to reset the SelectedItem to null, that's why you are getting always the first list item clicked.
Your code should look like this:
async void Handle_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var monkey = e.SelectedItem as Monkey;
if (monkey == null)
return;
await Navigation.PushAsync(new DetailsPage(monkey)); // always await Navigations
((ListView)sender).SelectedItem = null;
}
P.S. Make your method async so you don't cause UI Thread to block
EDIT
Try to get the selected item from SelectedItemChangedEventArgs.
var monkey = e.SelectedItem as Monkey;
UPDATE
Okay the SelectedItem is being updated successfully but the 'Monkey Item' on the ViewModel behind the DetailsPage is not!
So on DetailsPage add this line:
public partial class DetailsPage : ContentPage
{
public DetailsPage(Monkey monkey)
{
InitializeComponent();
BindingContext = new DetailsViewModel(monkey); // Update the BindingContext
}
}
And remove this line on the DetailsPage.xaml:
BindingContext="{x:Static design:ViewModelLocator.DetailsViewModel}"

ListView Data Binding in Xamarin Forms without using GetDashboard button

On Login or Navigating to Dashboard Page, fetching data from API, I am using an extra button (Show Communities) to fetch my Fetch my Data. here is my code
<StackLayout BackgroundColor="#30af91" Padding="60" VerticalOptions="Center">
<Entry Text="{Binding Username}" Placeholder="Username"/>
<Entry Text="{Binding Password}" IsPassword="True" Placeholder="Password"/>
<Button Command="{Binding LoginCommand}" Text="Login" Clicked="Button_OnClicked"/>
</StackLayout>
Button_OnClicked only navigate to Dashboard page
private async void Button_OnClicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new Dashboard());
}
LoginCommand in LoginViewModel
public ICommand LoginCommand
{
get
{
return new Command(async() =>
{
var accesstoken = await _apiServices.LoginAsync(Username, Password);
Settings.AccessToken = accesstoken;
});
}
}
Here is my Dashboard Page
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:epolleasy.ViewModels;assembly=epolleasy"
x:Class="epolleasy.Views.Dashboard">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<ContentPage.BindingContext>
<viewModels:DashboardViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Button x:Name="BtnActiveForm" Text="Active Forms" Clicked="BtnActiveForm_OnClicked"></Button>
<Button x:Name="BtnCommunity" Text="My Communities" Clicked="BtnCommunity_OnClicked"></Button>
<Button x:Name="BtnHistory" Text="Sealed Forms" Clicked="BtnHistory_OnClicked"></Button>
<Button Text="Logout" Command="{Binding LogoutCommand}" Clicked="Logout_OnClicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
</MasterDetailPage.Master>
</MasterDetailPage>
Here is my Communities page where i am using an extra button using GetDashboard Command
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:epolleasy.ViewModels;assembly=epolleasy"
x:Class="epolleasy.Views.DpCommunities">
<ContentPage.BindingContext>
<viewModels:DashboardViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add New"
Icon="add.png"
Priority="0"
Clicked="MenuItem_OnClicked"/>
</ContentPage.ToolbarItems>
<StackLayout>
<Button Command="{Binding GetDashboard}" Text="Show Communities"/>
<ListView ItemsSource="{Binding UserDashboard.Com}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding CommunityName}"/>
<Label Text="{Binding CommunityUsers.Count}"/>
<Label Text="{Binding FormsCommunity.Count}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Here is GetDashboard Command in my ViewModel
public ICommand GetDashboard
{
get
{
return new Command(async () =>
{
var accessToken = Settings.AccessToken;
UserDashboard = await _apiServices.GetDashboard(accessToken);
});
}
}
Here is my UserDashboard in the same view model.
public Dashboard UserDashboard
{
get { return _userDashboard; }
set
{
_userDashboard = value;
OnPropertyChanged();
}
}
I want to get rid of that extra button.
every page has an OnAppearing method that fires when the page is display. You can use this to load your data instead of having the user click a button.
public override async void OnAppearing() {
base.OnAppearing();
var accessToken = Settings.AccessToken;
UserDashboard = await _apiServices.GetDashboard(accessToken);
}

How to display a ListView and Other Controls in a ScrollView?

I want to display a ListView and other controls inside a ScrollView. All is bound to a ViewModel. My attempts failed because it's not recommend to put a ListView inside a ScrollView. As I use a complex ViewCell DataTemplate, I did not consider to add my items in the code behind file as Buttons instead of a ListView.
Hope someone can show me a Xaml or CS pattern to achieve my goal.
Please only suggest a solution which works on iOS and Android!
Thanks
Eric
This is XAML code
<ScrollView Padding="2">
<StackLayout HorizontalOptions="FillAndExpand">
<Grid HorizontalOptions="FillAndExpand">
<StackLayout>
<ScrollView Orientation="Horizontal">
<ListView BackgroundColor="Transparent" ItemsSource="{Binding UsersList}" SeparatorVisibility="None" x:Name="YourListView" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="Transparent" Padding="5">
<Button Text="{Binding UserName}" WidthRequest="115" HorizontalOptions="FillAndExpand" TextColor="White" BackgroundColor="#4b76c4" FontAttributes="Bold" FontSize="20" FontFamily="Avenir Book"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
</StackLayout>
</Grid>
</StackLayout>
</ScrollView>
and .cs file you need set BindingContext
BindingContext = new YourViewModel();
Solution:
As Rodrigo E suggested I download the latest Xamarin Evolve App 2016. After digging through the code I adjusted/simplified the FeedPage.xaml in the solution to that:
<?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:local="clr-namespace:XamarinEvolve.Clients.UI;assembly=XamarinEvolve.Clients.UI"
xmlns:pull="clr-namespace:Refractored.XamForms.PullToRefresh;assembly=Refractored.XamForms.PullToRefresh"
x:Class="XamarinEvolve.Clients.UI.FeedPage"
x:Name="FeedPage"
Title="Evolve Feed"
Icon="tab_feed.png"
BackgroundColor="{DynamicResource WindowBackgroundTable}">
<pull:PullToRefreshLayout
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsBusy}">
<local:AlwaysScrollView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout>
<StackLayout Spacing="0">
<local:NonScrollableListView
x:Name="ListViewSessions"
ItemsSource="{Binding Sessions}">
<local:NonScrollableListView.RowHeight>
<OnPlatform x:TypeArguments="x:Int32" Android="50" iOS="50" WinPhone="50"/>
</local:NonScrollableListView.RowHeight>
<local:NonScrollableListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Button Text="{Binding Title}" BackgroundColor="Black" TextColor="Green" />
</ViewCell>
</DataTemplate>
</local:NonScrollableListView.ItemTemplate>
</local:NonScrollableListView>
</StackLayout>
<StackLayout Padding="0" Spacing="0" BackgroundColor="Green">
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
</StackLayout>
</StackLayout>
</local:AlwaysScrollView>
</pull:PullToRefreshLayout>
There are a few things to do:
In the FeedViewModel.cs I added that code for a quick test:
async Task ExecuteLoadSessionsCommandAsync()
{
if (LoadingSessions)
return;
LoadingSessions = true;
try
{
NoSessions = false;
Sessions.Clear();
OnPropertyChanged("Sessions");
#if DEBUG
await Task.Delay(1000);
#endif
var sessions = await StoreManager.SessionStore.GetNextSessions();
var testSessions = new List<Session>();
testSessions.Add(new Session
{
Title = "TEST"
});
testSessions.Add(new Session
{
Title = "TEST"
});
testSessions.Add(new Session
{
Title = "TEST"
});
sessions = testSessions;
if(sessions != null)
Sessions.AddRange(sessions);
NoSessions = Sessions.Count == 0;
}
catch(Exception ex)
{
ex.Data["method"] = "ExecuteLoadSessionsCommandAsync";
Logger.Report(ex);
NoSessions = true;
}
finally
{
LoadingSessions = false;
}
}
You have to reference the package Refractored.XamForms.PullToRefresh to get the Pull-to-Refresh behavor.
This is in that namespace referenced: xmlns:pull="clr-namespace:Refractored.XamForms.PullToRefresh;assembly=Refractored.XamForms.PullToRefresh"
You have to Copy the AlwaysScrollView , NonScrollableListView to your PCL library.
refercene it with: xmlns:local="clr-namespace:"
In your iOS Project add that custom ListView Renderer:
public class NonScrollableListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (Control != null)
Control.ScrollEnabled = false;
}
}
public class AlwaysScrollViewRenderer : ScrollViewRenderer
{
public static void Initialize()
{
var test = DateTime.UtcNow;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.AlwaysBounceVertical = true;
}
}
See file: Renderer
Put that CollectionChanged Handler in your Code-behind file:
ViewModel.Sessions.CollectionChanged += (sender, e) =>
{
var adjust = Device.OS != TargetPlatform.Android ? 1 : -ViewModel.Sessions.Count + 1;
ListViewSessions.HeightRequest = (ViewModel.Sessions.Count * ListViewSessions.RowHeight) - adjust;
};
See File FeedPage.cs.xaml: FeedPage.cs.xaml

Resources