i have follow grial grid to enable the itemClickCommand.
below is the source code DashboardMultipleTilesPage.xaml:
<grial:GridView
WidthRequest="320"
Margin="0"
Padding="10"
ColumnSpacing="10"
RowSpacing="10"
ItemsSource="{ Binding Items }"
ItemClickCommand="{ Binding ItemCommand }"
ItemTemplate="{ StaticResource Selector }"
ColumnCount="2"/>
and below is from DashboardMultipleTilesViewModel.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows.Input;
using UXDivers.Grial;
using Xamarin.Forms;
namespace QlikApps
{
public class DashboardMultipleTilesViewModel :ObservableObject
{
private readonly Command _itemCommand;
public ICommand ItemCommand => _itemCommand;
public DashboardMultipleTilesViewModel(): base(listenCultureChanges: true)
{
_itemCommand = new Command<DashboardMultipleTilesPage>(ItemAction);
LoadData();
}
public ObservableCollection<DashboardMultipleTileItemData> Items { get; } = new ObservableCollection<DashboardMultipleTileItemData>();
protected override void OnCultureChanged(CultureInfo culture)
{
LoadData();
}
private void LoadData()
{
Items.Clear();
JsonHelper.Instance.LoadViewModel(this, source:"NavigationDashboards.json");
}
private void ItemAction(DashboardMultipleTilesPage items)
{
Application.Current.MainPage.DisplayAlert("Hello",
items.Title, "OK");
string id = items.id;
}
}
}
ItemAction(DashboardMultipletilesPage item) not fire at all?
How to access data which currently point to the grid?
please help.
You can improve
public ICommand ItemCommand {get; set;}
And
ItemCommand = new Command<DashboardMultipleTilesPage>(ItemAction);
Update:
Make sure you have set the BindingContext in your ContentPage.
Related
My Datagrid does not populate after I click a button in my ViewModel
Model Code:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Mist_Management.SubmissionStatusBySite
{
public class Table
{
[JsonProperty("Company")]
public string Company { get; set; }
[JsonProperty("DATE")]
public string Date { get; set; }
[JsonProperty("EODNUMBER")]
public string EODNumber { get; set; }
[JsonProperty("SUBSTATUS")]
public string SubStatus { get; set; }
[JsonProperty("DAYENDSTATUS")]
public string DayEndStatus { get; set; }
}
public class BySite
{
public List<Table> Table { get; set; }
}
}
ViewModel Code:
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Mist_Management.CompanyModels;
using Mist_Management.SubmissionStatusBySite;
using System;
using System.Diagnostics;
namespace Mist_Management.ViewModels
{
class SubmissionStatusBySiteViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public ObservableCollection<CompanyModels.Table> Company { get; set; }
public ObservableCollection<SubmissionStatusBySite.Table> BySite { get; set; }
public SubmissionStatusBySiteViewModel()
{
Company = new ObservableCollection<CompanyModels.Table>();
GetCompany();
}
private async void GetCompany()
{
string requestUrl = "https://mist.zp.co.za:6502/MIST.svc/CMP/M#H$#203#R";
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
string content = await response.Content.ReadAsStringAsync();
Company root = JsonConvert.DeserializeObject<Company>(content);
List<CompanyModels.Table> dates = root.Table;
foreach (var item in dates)
{
Company.Add(item);
}
}
}
}
public CompanyModels.Table selectedCompany;
public CompanyModels.Table SelectedCompany
{
get { return selectedCompany; }
set
{
selectedCompany = value;
OnPropertyChanged("SelectedCompany");
Debug.WriteLine(value.Company);
}
}
public DateTime _selectedFromDate;
public DateTime SelectedFromDate
{
get { return _selectedFromDate; }
set
{
if (_selectedFromDate == value)
return;
_selectedFromDate = value;
Debug.WriteLine(_selectedFromDate);
}
}
public string FromDate
{
get
{
return this.SelectedFromDate.ToString("yyyy-MM-dd");
}
}
public DateTime _selectedEndDate;
public DateTime SelectedEndDate
{
get { return _selectedEndDate; }
set
{
if (_selectedEndDate == value)
return;
_selectedEndDate = value;
Debug.WriteLine(_selectedEndDate);
}
}
public string EndDate
{
get
{
return this.SelectedEndDate.ToString("yyyy-MM-dd");
}
}
private async void GetData()
{
string requestUrl = "https://mist.zp.co.za:6502/MIST.svc/SUB2/M#H$#203#R/"
+ selectedCompany.Company + "/" + FromDate + "/" + EndDate;
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(requestUrl);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
string content = await response.Content.ReadAsStringAsync();
BySite root = JsonConvert.DeserializeObject<BySite>(content);
List<SubmissionStatusBySite.Table> dates = root.Table;
foreach (var item in dates)
{
BySite.Add(item);
}
}
}
Debug.WriteLine(requestUrl);
}
public ICommand LoadButton_Clicked
{
get
{
return new Command(() =>
{
BySite = new ObservableCollection<SubmissionStatusBySite.Table>();
GetData();
});
}
}
}
}
XAML code:
<?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:dg="clr-namespace:Xamarin.Forms.DataGrid;assembly=Xamarin.Forms.DataGrid"
xmlns:system="clr-namespace:System;assembly=mscorlib"
x:Class="Mist_Management.Views.SubmissionStatusBySite"
Title="Submission Status By Site">
<StackLayout>
<Picker Title="Company List" ItemsSource="{Binding Company}"
ItemDisplayBinding="{Binding Company}"
SelectedItem="{Binding SelectedCompany}"/>
<Label Text="From Date"
FontSize="Medium"/>
<DatePicker HorizontalOptions="CenterAndExpand"
Format="yyyy-MM-dd"
MinimumDate="2015-01-01"
Date="{Binding SelectedFromDate}"/>
<Label Text="To Date"
FontSize="Medium"/>
<DatePicker HorizontalOptions="CenterAndExpand"
x:Name="EndDate"
Format="yyyy-MM-dd"
MinimumDate="2015-01-01"
Date="{Binding SelectedEndDate}"/>
<Button Text="Load" Command="{Binding LoadButton_Clicked}"/>
<ContentView>
<ScrollView Orientation="Horizontal">
<dg:DataGrid x:Name="BySiteGrid" ItemsSource="{Binding BySite}" RowHeight="70" HeaderHeight="50"
BorderColor="#CCCCCC" HeaderBackground="#E0E6F8">
<x:Arguments>
<ListViewCachingStrategy>RetainElement</ListViewCachingStrategy>
</x:Arguments>
<dg:DataGrid.HeaderFontSize>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Tablet>15</OnIdiom.Tablet>
<OnIdiom.Phone>12</OnIdiom.Phone>
</OnIdiom>
</dg:DataGrid.HeaderFontSize>
<dg:DataGrid.Columns>
<dg:DataGridColumn Title="Company" PropertyName="Company" Width="200"/>
<dg:DataGridColumn Title="Date" PropertyName="Date" Width="150"/>
<dg:DataGridColumn Title="EOD Number" PropertyName="EODNumber" Width="150"/>
<dg:DataGridColumn Title="Sub Status" PropertyName="SubStatus" Width="150"/>
<dg:DataGridColumn Title="Day End Status" PropertyName="DayEndStatus" Width="150"/>
</dg:DataGrid.Columns>
</dg:DataGrid>
</ScrollView>
</ContentView>
</StackLayout>
</ContentPage>
ContentView Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Mist_Management.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SubmissionStatusBySite : ContentPage
{
public SubmissionStatusBySite()
{
InitializeComponent();
BindingContext = new ViewModels.SubmissionStatusBySiteViewModel();
}
}
}
I have other content viewModels that load on screen create but when I click a button the Datagrid does not want to load.
I have tried everything I can think off. I'm at my end with this problem.
Any help would be appreciated
We have a really simple app, the idea is the timer will update a label on the home screen depending on different configuration within the mobile app. I have created the binding and can update the homepage from it's self but not from the timer. I think what is missing is a OnChange within the home page to detect if the string has changed.
Display layout code, bind the label to the name "LabelText"
<Label
Text = "{Binding LabelText, Mode=TwoWay}"
x:Name="MainPageStatusText"
HorizontalOptions="CenterAndExpand"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="6"
VerticalOptions="CenterAndExpand"
TextColor="White"
FontSize="Medium"/>
This is the class file to link the text string to the label, I can see it been called from the different places but when it's called from the app.cs it does not work
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace Binding_Demo
{
public class MyClass : INotifyPropertyChanged
{
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{ PropertyChanged?.Invoke(this, e); }
protected void OnPropertyChanged(string propertyName)
{ OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); }
public event PropertyChangedEventHandler PropertyChanged;
private string labelText;
public string LabelText
{
get {
return labelText;
}
set
{
labelText = value;
OnPropertyChanged("LabelText");
}
}
}
}
This is the code inside the homepage, this works and I can see it sending data to the text label
public static MyClass _myClass = new MyClass();
public Homepage()
{
BindingContext = _myClass;
_myClass.LabelText = "Inside the home page";
}
This is the App.cs code, we start the timer and then want to set the text on the Homepage label. I can see the class been called, but it does not set the text.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Binding_Demo
{
public partial class App : Application
{
public static MyClass _myClass = new MyClass();
public App()
{
//InitializeComponent();
Device.StartTimer(TimeSpan.FromSeconds(10), () =>
{
Task.Run(() =>
{
Debug.WriteLine("Timer has been triggered");
// !!!!! This is not setting the text in the label !!!!!
BindingContext = _myClass;
_myClass.LabelText = "Inside the timer app";
});
return true; //use this to run continuously
});
MainPage = new NavigationPage(new MainPage());
}
protected override void OnStart()
{
//
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
// force app to mainpage and clear the token
}
}
}
I have created the binding and can update the homepage from it's self but not from the timer.
As Jason said, please make sure the binding model is unique. You could create a global static instance of MyClass in App class, then bind this instance to HomePage.
Check the code:
App.xaml.cs
public partial class App : Application
{
public static MyClass _myClass = new MyClass();
public App()
{
InitializeComponent();
Device.StartTimer(TimeSpan.FromSeconds(5), () =>
{
Task.Run(() =>
{
_myClass.LabelText = "Inside the timer app";
});
return true;
});
MainPage = new NavigationPage(new Homepage());
}
}
Homepage.xaml.cs:
public Homepage()
{
InitializeComponent();
BindingContext = App._myClass;
}
I have been trying to bind my ListView to my View model. The view model successfully retrieves 5 records from the database and the Listview seems to display 5 blank rows, however it is not showing binding for each field within each row.
I have spent a couple of days searching internet but I don't seem to be doing anything different. I was using master detail pages so I thought that it may be the issue so I set my Events page as first navigation page without master/detail scenario but to no avail. Please note that I am using Portable Ninject for my dependencies/IoC.
My App.Xamal.cs is is as follows:
public App (params INinjectModule[] platformModules)
{
InitializeComponent();
var eventsPage = new NavigationPage(new EventsPage());
//Register core services
Kernel = new StandardKernel(new MyAppCoreModule(), new MyAppNavModule(eventsPage.Navigation));
//Register platform specific services
Kernel.Load(platformModules);
//Get the MainViewModel from the IoC
eventsPage.BindingContext = Kernel.Get<EventsViewModel>();
((BaseViewModel)(eventsPage.BindingContext)).Init();
MainPage = eventsPage;
}
My EventsPage.Xaml is provided below:
<?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="MyApp.Views.EventsPage"
Title="Events">
<ContentPage.Content>
<ListView x:Name="Events" ItemsSource="{Binding Events}" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding EventID}" BackgroundColor="Red" TextColor="White"
FontAttributes="Bold" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
My EventsPage.xaml.cs is provided below:
namespace MyApp.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EventsPage : ContentPage, IBaseViewFor<EventsViewModel>
{
public EventsPage ()
{
InitializeComponent ();
}
EventsViewModel _vm;
public EventsViewModel ViewModel
{
get => _vm;
set
{
_vm = value;
BindingContext = _vm;
}
}
}
}
My EventsViewModel is as follows, it successfully retrieves 5 records and OnPropertyChanged is fired for Events property:
namespace MyApp.ViewModels
{
public class EventsViewModel : BaseViewModel, IBaseViewModel
{
ObservableCollection<Event> _events;
readonly IEventDataService _eventDataService;
public ObservableCollection<Event> Events
{
get { return _events; }
set
{
_events = value;
OnPropertyChanged();
}
}
public EventsViewModel(INavService navService, IEventDataService eventDataService) : base(navService)
{
_eventDataService = eventDataService;
Events = new ObservableCollection<Event>();
}
public override async Task Init()
{
LoadEntries();
}
async void LoadEntries()
{
try
{
var events = await _eventDataService.GetEventsAsync();
Events = new ObservableCollection<Event>(events);
}
finally
{
}
}
}
}
My BaseViewModel is as follows:
namespace MyApp.ViewModels
{
public abstract class BaseViewModel : INotifyPropertyChanged
{
protected INavService NavService { get; private set; }
protected BaseViewModel(INavService navService)
{
NavService = navService;
}
bool _isBusy;
public bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
OnPropertyChanged();
OnIsBusyChanged();
}
}
protected virtual void OnIsBusyChanged()
{
}
public abstract Task Init();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
// Secod BaseViewModel abstract base class with a generic type that will be used to pass strongly typed parameters to the Init method
public abstract class BaseViewModel<TParameter> : BaseViewModel
{
protected BaseViewModel(INavService navService) : base(navService)
{
}
public override async Task Init()
{
await Init(default(TParameter));
}
public abstract Task Init(TParameter parameter);
}
}
IBaseViewModel is just a blank interface:
public interface IBaseViewModel
{
}
IBaseViewFor is given below:
namespace MyApp.ViewModels
{
public interface IBaseViewFor
{
}
public interface IBaseViewFor<T> : IBaseViewFor where T : IBaseViewModel
{
T ViewModel { get; set; }
}
}
My Event model is as follows:
namespace MyApp.Models
{
public class Event
{
public int EventID;
}
}
Finally, the image of the output, as you can see that 5 rows are created with red background but EventID is not binding in each row. I have checked the data and EventID is returned. I have even tried to manually add records into Events list but to no avail, see the manual code and image below:
async void LoadEntries()
{
try
{
Events.Add((new Event() { EventID = 1 }));
Events.Add((new Event() { EventID = 2 }));
Events.Add((new Event() { EventID = 3 }));
Events.Add((new Event() { EventID = 4 }));
Events.Add((new Event() { EventID = 5 }));
}
finally
{
}
}
I have spent a lot of time on it but unable to find a reason for this anomaly, can someone please cast a fresh eye and provide help!?
You can only bind to public properties - ie, you need a getter
public class Event
{
public int EventID { get; set; }
}
I have a Xamarin.Forms app that uses Alex Rainman's CarouselView (https://github.com/alexrainman/CarouselView) to present a carousel (surprise! :) ). Each page in the carousel consists of a list of items. On Android it looks like this:
It is similar on Windows. However, on iOS I get this:
At first I thought it was a bug in the CarouselView component and submit an issue but the author said it was working fine on his side. I tried to debug it in whatever ways I could think of but couldn't find the problem. The CarouselView is instantiated and added to the view hierarchy. The ViewModel is instantiated and working fine if I replace it with say a ListView displaying the columns. Now I'm out of ideas and would really appreciate some help!
Here is my code:
MainPage.xaml:
<controls:CarouselViewControl Orientation="Horizontal"
InterPageSpacing="0"
Position="0"
ItemsSource="{Binding Columns}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
BackgroundColor="Gray"
ShowIndicators="True"
ShowArrows="True">
<controls:CarouselViewControl.ItemTemplate>
<DataTemplate>
<ContentView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Padding="20">
<ListView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="LightGray"
Header="{Binding Name}"
ItemsSource="{Binding Tasks}"
ItemSelected="ListView_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding Image}"
Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentView>
</DataTemplate>
</controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl>
(The code behind just calls InitializeComponent() in the constructor)
ColumnsViewModel.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ProofOfConcept
{
public class ColumnsViewModel : BindableObject
{
public static readonly BindableProperty PositionProperty = BindableProperty.Create(nameof(Position), typeof(int), typeof(ColumnsViewModel), 0, BindingMode.TwoWay);
public ObservableCollection<Column> Columns { get; set; }
public int Position
{
get { return (int)this.GetValue(PositionProperty); }
set { this.SetValue(PositionProperty, value); }
}
public ColumnsViewModel()
{
Columns = new ObservableCollection<Column>();
Random random = new Random();
for (int i = 0; i < 10; i++)
{
Column column = new Column
{
Name = String.Format("Column {0}", i),
Background = Color.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255))
};
ObservableCollection<Task> tasks = new ObservableCollection<Task>();
for (int t = 0; t < 25; t++)
{
Task task = new Task
{
Title = String.Format("Column #{0}, Task #{1}", i, t),
Color = Color.Lavender
};
tasks.Add(task);
}
column.Tasks = tasks;
Columns.Add(column);
}
}
}
}
Column.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ProofOfConcept
{
public class Column
{
public string Name { get; set; }
public ObservableCollection<Task> Tasks { get; set; }
public Color Background { get; set; }
public string Image
{
get
{
return "http://loremflickr.com/100/100";
}
}
}
}
Task.cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ProofOfConcept
{
public class Task : BindableObject
{
public static readonly BindableProperty ColorProperty = BindableProperty.Create(nameof(Color), typeof(Color), typeof(Task), Color.White, BindingMode.TwoWay);
public string Title { get; set; }
public string Assignee
{
get
{
return "Ivan";
}
}
public Color Color
{
get { return (Color)this.GetValue(ColorProperty); }
set { this.SetValue(ColorProperty, value); }
}
public string Image
{
get
{
return "http://loremflickr.com/100/100";
}
}
}
}
Also, here is a zip of the whole solution (without the Windows project since it was very big and not really relevant).
Usage
In your iOS and Android projects call:
Xamarin.Forms.Init();
CarouselViewRenderer.Init();
namespace ProofOfConcept.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
CarouselViewRenderer.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}
In case anyone have this issues in iOS even after calling "init". You can try giving height request to the CarouselViewControl. This is mostly the case if the control is in a grid and you are using Auto for RowDefinitin.Height
I want to make a simple login UI in xaml using Xamarin. I create a username and password field with Entry in the MainPage and then I try to bind them to my LoginViewModel where I can access my connexion method.
When I define the Binding context in the Mainpage codebehind the application simply shutdown and I dont understand why, what am I doing wrong ?
MainPage.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"
xmlns:local="clr-namespace:suivAAndroid"
x:Class="suivAAndroid.MainPage">
<StackLayout
VerticalOptions="CenterAndExpand">
<Image></Image>
<Label
Text="Login"
StyleId="lbl_login"></Label>
<Entry
StyleId="ent_login"
Text="{Binding Username}"></Entry>
<Label
Text="Mot de passe"
StyleId="ent_mdp"></Label>
<Entry
StyleId="ent_mdp"
Text="{Binding Password}"></Entry>
<Button
Clicked="connexion_click"
Text="Connexion"></Button>
</StackLayout>
</ContentPage>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace suivAAndroid
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new LoginViewModel(); // Here is where it does not work. If the line is commented out, then the application launch without stopping but because there is no binding context I cant get the user inputs.
}
private void connexion_click(object sender, EventArgs e)
{
LoginViewModel connexionBtn = new LoginViewModel();
Device.BeginInvokeOnMainThread(async () =>
{
await connexionBtn.Connexion();
});
}
}
}
LoginViewModel.cs
using suivAAndroid.Models;
using suivAAndroid.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace suivAAndroid
{
public class LoginViewModel
{
#region propriétés
public string Username
{
get
{
return Username;
}
set
{
Username = value;
}
}
public string Password
{
get
{
return Password;
}
set
{
Password = value;
}
}
#endregion
#region constructor
public LoginViewModel()
{
}
#endregion
#region methodes
public void CreerListeVisiteurDur(List<Visiteur> uneListe)
{
Visiteur unVisiteur = new Visiteur("Clooney", "George", "cgeorge", "azerty", "rue du port", "59", "lille", new DateTime(2015 / 07 / 13));
uneListe.Add(unVisiteur);
}
public async Task Connexion()
{
List<Visiteur> uneListe = new List<Visiteur>();
CreerListeVisiteurDur(uneListe);
if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password))
{
foreach (Visiteur unVisiteur in uneListe)
{
string login = unVisiteur.login;
string pass = unVisiteur.mdp;
if (login == Username && pass == Password)
{
App.Current.MainPage = new CreerVisite();
}
}
}
}
#endregion
}
}
Your ViewModel properties have infinite loops:
public string Username
{
get
{
return Username;
}
set
{
Username = value;
}
}
calling Username = value will call set on Username which in turn calls Username = value again.
Also, in order for your ViewModel to be bindable, you must implement INotifyPropertyChanged.
If you want a framework that is easy to use to help you do this, I would suggest Mvvm Light.
Here's an example of what your ViewModel should look like:
public class MyViewModel : INotifyPropertyChanged
{
public event EventHandler<PropertyChangedEventArgs> OnPropertyChanged;
private string _username;
public string Username
{
get
{
return _username;
}
set
{
_username = value;
PropertyChanged?.Invoke(new PropertyChangedEventArgs("Username");
}
}
....
}
in connexion_click you are creating a new copy of your VM that has no relation to the prior copy you created for your BindingContext.
public partial class MainPage : ContentPage
{
private LoginViewModel vm;
public MainPage()
{
InitializeComponent();
vm = new LoginViewModel();
BindingContext = vm;
}
private void connexion_click(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(async () =>
{
await vm.Connexion();
});
}
}
your VM should implement INotifyPropertyChanged
your VM has a recursive getter