I try to populate a Labeltext inside a Listview in XAML. But i want the Labeltext coming from the AppResources. I am shure i forgot somewhere a tiny lil detail like a using or namespace.
Anway, here's the XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Arbeitszeitrechner_Forms.Views.WorkdayListPage"
Style="{StaticResource PageStyle}"
Title="{Binding Title}"
xmlns:local="clr-namespace:Arbeitszeitrechner_Forms.ViewModels"
xmlns:model="clr-namespace:Arbeitszeitrechner_Forms.Models"
xmlns:appres="clr-namespace:Arbeitszeitrechner_Forms.Resources">
<!--Titel im WorkdaysViewModel zugewiesen und im AppResources definiert-->
<RefreshView x:DataType="local:WorkdaysViewModel" Command="{Binding LoadWorkdaysCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<CollectionView x:Name="WorkdaysListView"
ItemsSource="{Binding Workdays}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10" x:DataType="model:WorkdayList">
<Label
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16">
<Label.Text>
<MultiBinding StringFormat="{}{0} {1:d}">
<Binding Path="Day" />
<Binding Path="Date" />
</MultiBinding>
</Label.Text>
</Label>
<StackLayout Orientation="Horizontal">
<Label x:Name="LblTotalTime"/> <!-- **************THIS LABEL IS THE **** THING THAT I CAN'T POPULATE****************-->
<Label Text="{Binding TimeTotal, StringFormat='{0:hh}:{0:mm}'}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="13" />
</StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:WorkdaysViewModel}}, Path=WorkdayTapped}"
CommandParameter="{Binding .}">
</TapGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
and the xaml.cs Code behind:
namespace Arbeitszeitrechner_Forms.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class WorkdayListPage : ContentPage
{
WorkdaysViewModel _viewModel;
public WorkdayListPage()
{
InitializeComponent();
BindingContext = _viewModel = new WorkdaysViewModel();
//Normally i would do something like this here, but for some reason i can't:
//LblTotalTime.Text = AppResources.LblTotalTime
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
}
The Bot asked me to provide some more details to compensate the much Code i copied. So please ignore the gibbery gabberish i am Texting here.
use the x:Static extension
<Label Text="{x:Static resources:AppResources.LblTotalTime}" />
Related
I am using ToolKits Expander and I am trying to bind a command, this is what I got so far:
public partial class AssignTaskPage : ContentPage
{
public AssignTaskPage()
{
InitializeComponent();
GetMathSubCatgories = new Command(() => MathSubCatgoriesCommand());
}
public ICommand GetMathSubCatgories { get; private set; }
void MathSubCatgoriesCommand()
{
Console.Write("Here");
}
}
And in my view
<xct:Expander Command="{Binding GetMathSubCatgories}">
<xct:Expander.Header>
<Frame Padding="10" Margin="10" HasShadow="False" BorderColor="LightGray" VerticalOptions="CenterAndExpand">
<StackLayout Orientation="Horizontal">
<Image Source="{Binding icon}" WidthRequest="25" HeightRequest="25"></Image>
<Label Text="{Binding name}" TextColor="{Binding textColor}" FontSize="Large" FontAttributes="Bold" HeightRequest="35" VerticalOptions="CenterAndExpand"></Label>
</StackLayout>
</Frame>
</xct:Expander.Header>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListView x:Name="SubCategories" ItemsSource="{Binding subCategories}" ItemSelected="SubCategories_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding name}" TextColor="#02cc9d" FontAttributes="Bold" HeightRequest="35" VerticalOptions="CenterAndExpand"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</xct:Expander>
This does not work at all, (I put a break point on Console.Write("Here"); and its not hitting it)
So I did some digging and found this tutorial:
https://www.syncfusion.com/kb/12154/how-to-bind-command-to-expander-in-itemtemplate-of-xamarin-forms-listview-sflistview
and here is the sample in git.
https://github.com/SyncfusionExamples/command-to-expander-in-itemtemplate-listview-xamarin
I understand what I have to do here, the problem I am facing is when this Command is called, I was looking to get a value and use it in my AssignTaskPage, but what the tutorial is saying to have a ViewModel which is in a separate file. So should I setup a MessagingCenter in my AssignTaskPage and call it in the ViewModel to get the value I want and pass it to AssignTaskPage?
Because your command isn't defined in the ViewModel that you're binding to.You could bind the command which is defined in your AssignTaskPage,and then bind the viewmodel for the parent element of the expander.
For example :
public partial class AssignTaskPage : ContentPage
{
public AssignTaskPage()
{
InitializeComponent();
GetMathSubCatgories = new Command(() => MathSubCatgoriesCommand());
BindingContext = this;
}
public ICommand GetMathSubCatgories { get; private set; }
void MathSubCatgoriesCommand(object obj)
{
DisplayAlert("Alert!", "" + (obj as Contact).ContactName + "expanded", "Ok");
}
}
the xaml (here use the xaml codes of the above sample),the grid bind the viewmodel,and your expander bind the command of the root (your page):
<?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:ExpanderXamarin"
x:Class="ExpanderXamarin.ExpandableListView"
x:Name="root"
xmlns:sflistview="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
xmlns:expander="clr-namespace:Syncfusion.XForms.Expander;assembly=Syncfusion.Expander.XForms">
<ContentPage.Content>
<Grid x:Name="mainGrid" BackgroundColor="#F0F0F0" Padding="4">
<Grid.BindingContext>
<local:ViewModel />
</Grid.BindingContext>
<sflistview:SfListView x:Name="listView" AutoFitMode="DynamicHeight" ItemsSource="{Binding ContactsInfo}">
<sflistview:SfListView.ItemTemplate>
<DataTemplate>
<Frame x:Name="frame" CornerRadius="2" Padding="{OnPlatform Android=1, iOS=1, UWP=0}" Margin="{OnPlatform Android=1, iOS=1, UWP=0}" OutlineColor="White" HasShadow="{OnPlatform Android=true, iOS=false, UWP=true}">
<Grid Padding="{OnPlatform Android=2, iOS=2, UWP=0}" Margin="{OnPlatform Android=1, iOS=1, UWP=0}" BackgroundColor="White" >
<expander:SfExpander x:Name="expander" HeaderIconPosition="None">
<expander:SfExpander.Behaviors>
<local:EventToCommandBehavior Command="{Binding Path=BindingContext.GetMathSubCatgories, Source={x:Reference root}}" EventName="Expanding" CommandParameter="{Binding .}"/>
</expander:SfExpander.Behaviors>
<expander:SfExpander.Header>
...
</expander:SfExpander.Header>
<expander:SfExpander.Content>
..
</expander:SfExpander.Content>
</expander:SfExpander>
</Grid>
</Frame>
</DataTemplate>
</sflistview:SfListView.ItemTemplate>
</sflistview:SfListView>
</Grid>
</ContentPage.Content>
</ContentPage>
if you want get the parameters you could bind the CommandParameter like above.
I have a listview in the content view,and I want to after refreshing hide a part of the page.Please help me to it.I tried to make a swipe but listview conflict with it.so I decided to try make with refresh
<ContentView.Content>
<controls:CustomFrame CornerRadius="25,25,0,0" Margin="0" Padding="10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout Padding="0">
<BoxView HorizontalOptions="Center" WidthRequest="40" HeightRequest="7" BackgroundColor="Gray" CornerRadius="15" />
<!-- <StackLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Up" Command="{Binding RefreshCommand}" ></SwipeGestureRecognizer>
</StackLayout.GestureRecognizers>-->
<ListView ItemsSource="{Binding MyPins}" RowHeight="100" x:Name="ListPlaces" IsPullToRefreshEnabled="True" RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"
SelectionMode="None">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Frame CornerRadius="10" BackgroundColor="LightBlue" Padding="10">
<StackLayout Orientation="Vertical" Padding="0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding BindingContext.CallPlace, Source={x:Reference ListPlaces}}" ></TapGestureRecognizer>
</StackLayout.GestureRecognizers>
<Label x:Name="NameOfPlace" Text="{Binding Name}" TextColor="#2D78FD" FontSize="14" FontFamily="Robobo"/>
<Label x:Name="AdressOfPlace" Text="{Binding Address}" TextColor="#616161" FontSize="12" FontFamily="Robobo"/>
<StackLayout Orientation="Horizontal">
<Label x:Name="TimeWork" VerticalOptions="Center" Text="Open until - " TextColor="#616161" FontSize="12" FontFamily="Robobo"/>
<Label x:Name="TimeWork1" VerticalOptions="Center" Text="{Binding Opened}" TextColor="#616161" FontSize="12" FontFamily="Robobo"/>
<Image Source="openIcon" VerticalOptions="Center" />
<Button HeightRequest="24" VerticalOptions="Center" Padding="0,-3,0,0" WidthRequest="92" HorizontalOptions="EndAndExpand" FontSize="14" CornerRadius="45" BackgroundColor="#2D78FD" TextColor="White" Text="Call up"/>
</StackLayout>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</controls:CustomFrame>
</ContentView.Content>
WHAT I WANT TO DO
Since you had used MVVM , there are many ways which can implements .
Option 1 :
We could set the IsVisible property of the ViewCell
in xaml
Define the property in the model
public class YourModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
bool isVisible;
public bool IsVisible
{
get
{
return isVisible;
}
set
{
if(value!=isVisible)
{
isVisible = value;
OnPropertyChanged("IsVisible");
}
}
//other property like name...
}
In ViewModel
CallPlace = new Command((org)=> {
YourModel model = org as YourModel;
model.isVisible = false;
});
Option 2
You could remove the item from MyPins
CallPlace = new Command((org)=> {
YourModel model = org as YourModel;
MySource.Remove(model);
});
I have a ViewModel, from which i construct a collection of objects. I want to be able to bind my objects on my view, while at the same time being able to use my button.
Currently, my properties are correctly bound to my labels (partnerLogo, partnerText, partnerLink). Unfortunately I'm not able to use my button command to send the command parameter that I bind.
ViewModel
Public class CarouselViewModel : INotifyPropertyChanged
{
public CarouselViewModel()
{
partners = new ObservableCollection<Carousel>()
{
new Carousel(){partnerText = "Test123", partnerLogo = "Test123", partnerLink = "Test123" },
};
openWebsite = new Command<string>((key) =>
{
Device.OpenUri(new Uri(key));
});
}
public ObservableCollection<Carousel> partners
{
get;
set;
}
public ICommand openWebsite
{
private set;
get;
}
}
XAML:
<CarouselView ItemsSource="{Binding partners}">
<CarouselView.ItemsLayout>
<GridItemsLayout/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame>
<StackLayout>
<Image Source="{Binding partnerLogo}"/>
<Label Text="{Binding partnerText}"/>
<Button Text="Read" Command="{Binding openWebsite}" CommandParameter="{Binding partnerLink}"/>
</StackLayout>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
How do I access my button command, while at the same time being able to send the commandparameter?
For each item in the CarouselView, the binding context will be underlying data item which is bound to ItemsSource i.e., Carousel. And for CarouselView, the binding context will be your ViewModel class if you have defined it.
To resolve the issue, set the x:Name="mycaroselview" to CarouselView in the XAML and refer it's path reference to the Button command as like below code example.
<CarouselView x:Name="MyCarousel" ItemsSource="{Binding partners}">
<CarouselView.ItemsLayout>
<GridItemsLayout/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame>
<StackLayout>
<Image Source="{Binding partnerLogo}"/>
<Label Text="{Binding partnerText}"/>
<Button Text="Read" Command="{Binding BindingContext.openWebsite, Source={x:Reference Name=MyCarousel}}" CommandParameter="{Binding partnerLink}"/>
</StackLayout>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
Make sure that you must set the binding context either to ContentPage or CarouselView.
Regards,
Dinesh
What you can do is, give a x:name to the content Page that you are using:-
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyProject;assembly= MyProject"
x:Class="MyProject.Views.MyPage"
x:Name="ThisPage">
And then give Source to the Command. Like this. This method will call the Command that is there in the ViewModel of the Current Page. Also, you can use a Command Parameter to know which Item has Triggered the Command.
<CarouselView ItemsSource="{Binding partners}">
<CarouselView.ItemsLayout>
<GridItemsLayout/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame>
<StackLayout>
<Image Source="{Binding partnerLogo}"/>
<Label Text="{Binding partnerText}"/>
<Button Text="Read" Command="{Binding openWebsite, Source={x:Reference Name=ThisPage}}" CommandParameter="{Binding partnerLink}"/>
</StackLayout>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
I am new to Xamarin Forms and trying to implement Infinite Loop Functionality in my app. The sample code that i followed is working fine and i have managed to integrate it into my app successfully.
The problem is that i am unable to find out how to change the source of the listview from the code.
I intend to have buttons above my listview (As in the following Image) and upon click the source of the listView should change.
This is how my code looks like
<ContentPage.BindingContext>
<local:MainViewModel />
</ContentPage.BindingContext>
<StackLayout>
<ListView x:Name="tyres_listview" ItemsSource="{Binding Items}"
HasUnevenRows="True" SeparatorVisibility="None" >
<ListView.Behaviors>
<extended:InfiniteScrollBehavior IsLoadingMore="{Binding IsBusy}" />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Grid Margin="10" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.25*"></ColumnDefinition>
<ColumnDefinition Width="0.75*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="5,5,5,10">
<Image Source="{Binding image_url}" >
</Image>
</StackLayout>
<StackLayout Grid.Column="1" Spacing="0" >
<Label Text="{Binding name}" FontAttributes="Bold" FontSize="Small" Margin="0,5,5,0" VerticalOptions="Center" ></Label>
<Label Text="{Binding brand}" VerticalOptions="Center" FontSize="Micro" ></Label>
<Label Text="{Binding item_id}" VerticalOptions="Center" FontSize="Micro" ></Label>
<StackLayout Orientation="Horizontal" x:Name="sl_db" >
<Image Source="fuel.png" ></Image>
<Label Text="{Binding fuel_type}"></Label>
<Image Source="weather.png"></Image>
<Label Text="{Binding wheather_type }"></Label>
<Image Source="volume.png" ></Image>
<Label Text="{Binding noise}"></Label>
<Label Text="dB"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Image></Image>
<Label Text="{Binding rated_count }"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Price: " VerticalOptions="Center"></Label>
<Label Text="{Binding price }" VerticalOptions="Center" TextColor="Green"></Label>
<Label Text=" EUR" VerticalOptions="Center"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" >
</TapGestureRecognizer>
</StackLayout.GestureRecognizers>
<StackLayout BackgroundColor="Red" Orientation="Horizontal" Margin="5" >
<Image Source="shoppingcart.png" Margin="10,0,0,0"></Image>
<Label Text="Add to Cart" VerticalOptions="Center" HorizontalOptions="EndAndExpand" Margin="0,0,10,0" ></Label>
</StackLayout>
<Image x:Name="button_info" Source="info.png" >
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="button_info_Clicked"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</StackLayout>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Footer>
<Grid Padding="6" IsVisible="{Binding IsBusy}">
<!-- set the footer to have a zero height when invisible -->
<Grid.Triggers>
<Trigger TargetType="Grid" Property="IsVisible" Value="False">
<Setter Property="HeightRequest" Value="0" />
</Trigger>
</Grid.Triggers>
<!-- the loading content -->
<Label Text="Loading..." TextColor="DeepPink" FontSize="20" FontAttributes="Bold" VerticalOptions="Center" HorizontalOptions="Center" />
</Grid>
</ListView.Footer>
</ListView>
<Button Clicked="button_Change_Order_Clicked"></Button>
</StackLayout>
public class MainViewModel : INotifyPropertyChanged
{
private bool _isBusy;
private const int PageSize = 10;
readonly DataService _dataService = new DataService();
public InfiniteScrollCollection<Product_Search> Items { get; }
public bool IsBusy
{
get => _isBusy;
set
{
_isBusy = value;
OnPropertyChanged();
}
}
public MainViewModel()
{
Items = new InfiniteScrollCollection<Product_Search>
{
OnLoadMore = async () =>
{
IsBusy = true;
// load the next page
var page = Items.Count / PageSize;
var items = await _dataService.GetItemsAsync(page, PageSize);
IsBusy = false;
// return the items that need to be added
return items;
},
OnCanLoadMore = () =>
{
return Items.Count < 44;
}
};
DownloadDataAsync();
}
private async Task DownloadDataAsync()
{
var items = await _dataService.GetItemsAsync(pageIndex: 0, pageSize: PageSize);
Items.AddRange(items);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Any help would be of great importance.
Your ListView.Items property is already bound to your MainViewModel.Items property, a PropertyChanged event needs to be triggered to signal a change on the property value (corresponding to the property itself or its content if InfiniteScrollCollection<> is an Observable collection).
When you would want to replace the Items source you can give it a new value, signal it has changed and your ListView might be refreshed:
private InfiniteScrollCollection<Product_Search> _items;
public InfiniteScrollCollection<Product_Search> Items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged();
}
}
I try using mvvm in my xamarin forms but i'm still litle bit confused with the navigation in each page, I Already Create Interface and NavigationService to handle all Navigation in my Xamarin Forms, there is no error code line but when i click the buton and try to navigate to other page it always crash. Here is some of my code
My Interface
namespace KGVC.Interfaces
{
public interface INavigationService
{
void NavigateToDashboard();
void NavigateToLogout();
void NavigateBack();
void gotoNews();
void goEvent();
void gotoKGCash();
void gotoCardCommnunity();
void gotoSetting();
void gotoNearbyLocation();
}
}
my navigationservice
namespace KGVC.Services
{
public class NavigationService : INavigationService
{
public void goEvent()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new EventPage());
}
public void gotoCardCommnunity()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new CardCommunityPage());
}
public void gotoKGCash()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new KGCashPage());
}
public void gotoNearbyLocation()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new StoreMaps());
}
public void gotoNews()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new RssFeedView());
}
public void gotoSetting()
{
var currentPage = GetCurrentPage();
currentPage.Navigation.PushAsync(new SettingPages());
}
public void NavigateBack()
{
throw new NotImplementedException();
}
public void NavigateToDashboard()
{
var currentPage = GetCurrentPage();
Application.Current.MainPage = new MainPage();
}
public void NavigateToLogout()
{
var currentPage = GetCurrentPage();
Application.Current.MainPage = new NewPageLogin();
}
private Page GetCurrentPage()
{
var currentPage = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
return currentPage;
}
}
}
my view model
public class GridMenuViewModel
{
public ICommand gotoNews { get; private set; }
public ICommand goEvent { get; private set; }
public ICommand gotoKGCash { get; private set; }
public ICommand gotoSetting { get; private set; }
public ICommand gotoNearbyLocation { get; private set; }
public GridMenuViewModel()
{
gotoNews = new Command(() =>
{
var navigationService = new NavigationService();
navigationService.gotoNews();
});
goEvent = new Command(() =>
{
var navigationService = new NavigationService();
navigationService.goEvent();
});
gotoKGCash = new Command(() =>
{
var navigationService = new NavigationService();
navigationService.gotoKGCash();
});
gotoSetting = new Command(() =>
{
var navigationService = new NavigationService();
navigationService.gotoSetting();
});
gotoNearbyLocation = new Command(() =>
{
var navigationService = new NavigationService();
navigationService.gotoNearbyLocation();
});
}
}
And my view
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
NavigationPage.HasNavigationBar="True"
NavigationPage.BackButtonTitle="False"
BindingContext="{Binding GridMenuViewModel, Source={StaticResource Locator}}"
xmlns:control="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
xmlns:local="clr-namespace:KGVC.Views.MainPages"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="KGVC.Views.MainPages.GridMenu"
Title="HOME"
>
<ContentPage.Content>
<StackLayout >
<StackLayout BackgroundColor="##CEB053">
<StackLayout HeightRequest="35" BackgroundColor="##CEB053" Orientation="Horizontal">
<Label FontAttributes="Italic" TextColor="Black" Margin="9" Text="Hello," FontSize="15"/>
<Label TextColor="Black" Margin="9" Text="John Doe" FontSize="15" FontAttributes="Bold"/>
</StackLayout>
<StackLayout Padding="0" HeightRequest="30" BackgroundColor="#E3E6E3" Orientation="Horizontal">
<Image Margin="5" Source="ic_logo.png"/>
<Label Text="Points" Margin="5" FontSize="13" TextColor="Black"/>
</StackLayout>
</StackLayout>
<StackLayout HeightRequest="220" VerticalOptions="StartAndExpand">
<control:CarouselView HeightRequest="185" ItemsSource="{Binding MyDataSource}" Position="{Binding Position, Mode=TwoWay}">
<control:CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}"/>
</DataTemplate>
</control:CarouselView.ItemTemplate>
</control:CarouselView>
<local:CarouselIndicators IndicatorHeight="9" IndicatorWidth="9" UnselectedIndicator="unselected_circle.png" SelectedIndicator="selected_circle.png" Position="{Binding Position}" ItemsSource="{Binding MyDataSource}" />
</StackLayout>
<ScrollView IsClippedToBounds="True" VerticalOptions="StartAndExpand" Orientation="Vertical" >
<Grid x:Name="controlGrid" VerticalOptions="StartAndExpand" HeightRequest="370" Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="0" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="110" />
</Grid.ColumnDefinitions>
<StackLayout Orientation="Vertical" Grid.Row="1" Grid.Column="0" >
<Button Image="ic_account.png" Margin="5"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="MY ACCOUNT" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="1" Grid.Column="1">
<Button Margin="5" Command="{Binding gotoCardCommunity}" Image="ic_card.png"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="CARD" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="1" Grid.Column="2">
<Button Margin="5" Command="{Binding goEvent}" Image="ic_event"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="PROMO" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Grid.Row="2" Grid.Column="0" Orientation="Vertical">
<Button Margin="5" Command="{Binding gotoNearbyLocation}" Image="ic_store"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="STORE LOCATIONS" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="2" Grid.Column="1">
<Button Margin="5" Command="{Binding gotoNews}" Image="ic_news"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="NEWS" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Grid.Row="2" Grid.Column="2" Orientation="Vertical">
<Button Margin="5" Command="{Binding gotoKGCash}" Image="ic_kgcash"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="E-WALLET" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="0">
<Button Margin="5" Image="ic_ecommerce"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="E-COMMERCE" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="1">
<Button Margin="5" Command="{Binding gotoSetting}" Image="ic_pointsummary.png"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="POINT SUMMARY" HorizontalOptions="Center"/>
</StackLayout>
<StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="2">
<Button Margin="5" Command="{Binding gotoSetting}" Image="ic_setting"
Style="{StaticResource plainButton}" />
<Label FontSize="12" Text="SETTINGS" HorizontalOptions="Center"/>
</StackLayout>
</Grid>
</ScrollView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
i already try change the navigation service to use pushmodalasync, make the navigation async but still crash, Anyone can help me ? and i'm not using prism , mvvmlight and other 3rd party mvvm nuget
It depends on your MainPage. Did you check if GetCurrentPage() actually returns something?
Try to change the GetCurrentPage() to:
Page GetCurrentPage() =>
Application.Current.MainPage.Navigation?.NavigationStack?.LastOrDefault() ??
Application.Current.MainPage;
Another problems that I spotted:
1. C# naming conventions are different from Java. Method names should start with a capital letter. Currently you have a pure mix.
2. Initialising the BindingContext in XAML the way you did will create the ViewModel twice due to a bug. Change it to:
<ContentPage
xmlns:vm="your-namespace.vm"
...>
<ContentPage.BindingContext>
<vm:GridMenuViewModel />
</ContentPage.BindingContext>
</ContentPage>
3. No need to recreate the NavigationService for each command. Reuse it in your ViewModel.
4. You have some corrupted XAML:
<StackLayout BackgroundColor="##CEB053">
Fix the hex code. Generally speaking you could enable XAMLC so you would get notified about XAML errors while building your code.
5. In order to use PushAsync your MainPage should be wrapped by NavigationPage.
6. You need to await async code execution:
public async Task GoToCardCommnunity()
{
var currentPage = GetCurrentPage();
await currentPage.Navigation.PushAsync(new CardCommunityPage());
}
Check over the list above and pay attention to the application output and exceptions.