Exception of type 'System.Collections.Generic.KeyNotFoundException' was thrown ? in Xamarin.Forms - xamarin

i wanna use simple database in Xamarin Forms. So i used this code;
public partial class DBExample : ContentPage
{
string _dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),"myDB.db3");
public DBExample ()
{
InitializeComponent ();
}
private async void InsertButton(object sender, EventArgs e)
{
SQLiteConnection db=null;
try
{
db = new SQLiteConnection(_dbPath);
}
catch (Exception ex)
{
await DisplayAlert(null, ex.Message, "OK");
}
db.CreateTable<Users>();
var maxPk = db.Table<Users>().OrderByDescending(c => c.Id).FirstOrDefault();
Users users = new Users()
{
Id = (maxPk == null ? 1 : maxPk.Id + 1),
Name = userName.Text
};
db.Insert(users);
await DisplayAlert(null,userName.Text + "saved","OK");
await Navigation.PopAsync();
}
}
and i have problem. You can see it in Headtitle.
"Exception of type 'System.Collections.Generic.KeyNotFoundException' was thrown"
im waiting your support. Thanks for feedback.

Related

How to transfer data from one page to another xamarin

I have three pages, I enter the data on the second page and transfer it to page number one, returning to it at the same time, there is no problem with this, I use navigation, like this:
private async void OnSaveTitleButtonCliked(object sender, EventArgs e)
{
var title_data = new LabelViewModel
{
Label = editor.Text,
Date = DateTime.Now
};
var mainpage = new MainPage();
mainpage.BindingContext = title_data;
await Navigation.PushAsync(mainpage);
}
But I also need to transfer this data to page number three, so that I can go there from the first page and see, I tried the mvvm, but so far I have not understood how it works.
Please tell me how to do it better:)
Pass data by constructor:
In Page1:
private async void GoToPage2(object sender, EventArgs e)
{
var title_data = new LabelViewModel
{
Label = editor.Text,
Date = DateTime.Now
};
//Pass the model here
var Page2 = new Page2(title_data);
await Navigation.PushAsync(Page2);
}
In Page2:
public partial class Page2 : ContentPage
{
public LabelViewModel model;
public Page2(LabelViewModel m) {
InitializeComponent();
this.model = m;
//You can use your model here
}
}
Pass data by public property:
In Page1:
private async void GoToPage2(object sender, EventArgs e)
{
var title_data = new LabelViewModel
{
Label = editor.Text,
Date = DateTime.Now
};
var Page2 = new Page2();
//Pass the model here
Page2.model = title_data;
await Navigation.PushAsync(Page2);
}
In Page2:
public partial class Page2 : ContentPage
{
public LabelViewModel model;
public Page2()
{
InitializeComponent();
//You can use your model here
Console.WriteLine(model.Label);
Console.WriteLine(model.Date);
}
}
Let me know if you have any questions.
I'll let some examples here
On the first page (who calls the second one)
private async void MenuLista(object sender, EventArgs e)
{
var item = (ModelosPPP)((Button)sender).BindingContext;
if (PopupRunnning != false)
return;
var page = new MenuListSV(item);
PopupRunnning = true;
page.Action += async (a, b) =>
{
switch (b)
{
case 1:
await DisplayAlert("PDF", null, "ok");
break;
case 2:
await DisplayAlert("Reenviar", null, "ok");
break;
case 3:
await DisplayAlert("Excluir", null, "ok");
break;
}
};
page.Disappearing += (c, d) =>
{
PopupRunnning = false;
};
await PopupNavigation.Instance.PushAsync(page);
}
in Second Page
public partial class MenuListSV : PopupPage
{
public MenuListSV(Models.ModelosPPP obj)
{
InitializeComponent();
BindingContext = obj;
}
public EventHandler<int> Action;
public async void MenuChoice(object sender, EventArgs e)
{
var btn = sender as Button;
switch (btn.Text)
{
case "Abrir PDF":
Action?.Invoke(this, 1);
break;
case "Reenviar":
Action?.Invoke(this, 2);
break;
case "Excluir":
Action?.Invoke(this, 3);
break;
}
await PopupNavigation.Instance.PopAsync();
}
}

null reference exception when i delete item from sync realm database in xamarin

I got a null reference exception after I delete any item from the sync realm database .
the item is deleted from the database but it throws the exception and craches
I don't know why it throws this exception or where is the null object .
but when I delete this line the exception disappears :
listView.ItemsSource = Employees;
PS : this exception appeared when I tried to sync the realm database online.
public MainPage()
{
InitializeComponent();
Initialize();
listView.ItemsSource = Employees;
}
private async Task Initialize()
{
_realm = await OpenRealm();
Employees = _realm.All<Employee>();
Entertainments= _realm.All<Entertainment>();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Employees)));
}
void OnDeleteClicked(object sender, EventArgs e)
{
try {
var o = _realm.All<Employee>().FirstOrDefault(c => c.EmpId == 4);
if (o != null)
_realm.Write(() => { _realm.Remove(o); });
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Employees)));
}
catch (Exception exp)
{
string msg = exp.Message;
}
}
here is a screenshot of the exception
THIS SOLVED THE EXCEPTION ! Thank youu . but the listview is not auto updated now !
According to your code and description, you want to delete item form realm database, and update Listview. I find you use PropertyChanged to want to update Employees, but it doesn't work, because you delete item from realm database, don't change Employees, so it is not fired PropertyChanged event.
List<Employee> Employees = new List<Employee>();
private async Task Initialize()
{
_realm = await OpenRealm();
Employees = _realm.All<Employee>().ToList(); ;
Entertainments = _realm.All<Entertainment>();
}
void OnDeleteClicked(object sender, EventArgs e)
{
try
{
var o = _realm.All<Employee>().FirstOrDefault(c => c.EmpId == 4);
if (o != null)
_realm.Write(() => { _realm.Remove(o); });
Employees = _realm.All<Employee>().ToList();
listView.ItemsSource = Employees;
}
catch (Exception exp)
{
string msg = exp.Message;
}
}
Helpful article for you:
https://dzone.com/articles/xamarinforms-working-with-realm-database

TaskCanceledException on Refit call

I am implementing a simple login screen with MvvmCross Forms and Refit.
The start of the authentication task is started by pressing the button that has the command 'LogInCommand'
<Button x:Name="loginButton" Text = "Login" HorizontalOptions = "Center"
VerticalOptions = "StartAndExpand" FontSize="24" Command="{ Binding LogInCommand }"/>
This will execute the following command in the AuthenticationViewModel:
#region commands
async Task LogInTaskAsync()
{
var errors = _validator.Validate(this);
if (!errors.IsValid)
{
_toastService.DisplayErrors(errors); //Display errors here.
}
else
{
using (new Busy(this))
{
try
{
Status = AuthenticationStatusEnum.LOADING;
// get access token
string accessToken = await _authenticationService.LogIn(_email, _password);
Debug.WriteLine(String.Format("Access Token:t {0} ", accessToken));
// save token on preferences.
Settings.AccessToken = accessToken;
Status = AuthenticationStatusEnum.LOGIN_SUCESS;
}
catch (TaskCanceledException ex) {
Debug.WriteLine("Timeout Operation ...");
}
catch (Exception ex)
{
MessagingCenter.Send(new object(), EventTypeName.EXCEPTION_OCCURRED, ex);
Status = AuthenticationStatusEnum.LOGIN_FAILED;
}
}
}
}
IMvxCommand _logInCommand;
public IMvxCommand LogInCommand =>
_logInCommand ?? (_logInCommand = new MvxCommand(async () => await LogInTaskAsync()));
An instance of the AuthenticationService that is working with refit is injected into the view model.
async public Task<string> LogIn(string email, string password)
{
Debug.WriteLine(String.Format("Login with {0}/{1}", email, password));
return await _authenticationRestService.getAuthorizationToken(new JwtAuthenticationRequestDTO()
{
Email = email,
Password = password
}).ContinueWith(t => t.Result.Data.Token, TaskContinuationOptions.OnlyOnRanToCompletion);
}
The Refit service specification is as follows:
[Headers("Accept: application/json")]
public interface IAuthenticationRestService
{
[Post("/")]
Task<APIResponse<JwtAuthenticationResponseDTO>> getAuthorizationToken([Body] JwtAuthenticationRequestDTO authorizationRequest);
}
The problem is that the task is always canceled, the TaskCanceledException exception is always thrown.
I also expose CoreApp where I configure context instances.
public class CoreApp : MvvmCross.Core.ViewModels.MvxApplication
{
public override void Initialize()
{
var httpClient = new HttpClient(new HttpLoggingHandler())
{
BaseAddress = new Uri(SharedConfig.BASE_API_URL),
Timeout = TimeSpan.FromMinutes(SharedConfig.TIMEOUT_OPERATION_MINUTES)
};
// Register REST services
Mvx.RegisterSingleton<IAuthenticationRestService>(() => RestServiceFactory.getService<IAuthenticationRestService>(httpClient));
Mvx.RegisterSingleton<IParentsRestService>(() => RestServiceFactory.getService<IParentsRestService>(httpClient));
Mvx.RegisterSingleton<IChildrenRestService>(() => RestServiceFactory.getService<IChildrenRestService>(httpClient));
CreatableTypes()
.InNamespace("Bullytect.Core.Services")
.EndingWith("ServiceImpl")
.AsInterfaces()
.RegisterAsLazySingleton();
Mapper.Initialize(cfg => {
cfg.CreateMap<ParentDTO, ParentEntity>();
cfg.CreateMap<SonDTO, SonEntity>();
});
Mvx.RegisterType<IValidator, Validator>();
RegisterAppStart(new CustomAppStart());
}
}
Someone knows how I can fix this. Thanks in advance!!

OnNavigatedTo in ViewModel isn't firing when page first loads

I'm trying to implement Azure Active Directory B2C in Xamarin.Forms. If I just copy their example, I can get it to work without a problem. But when I try to use Prism, I run into problems.
I took this code that was sitting in the codebehind of the XAML:
protected override async void OnAppearing ()
{
base.OnAppearing ();
App.PCApplication.PlatformParameters = platformParameters;
try {
var ar = await App.PCApplication.AcquireTokenSilentAsync(
AuthenticationInfo.Scopes, string.Empty, AuthenticationInfo.Authority,
AuthenticationInfo.SignUpSignInpolicy, false);
AuthenticationInfo.UserAuthentication = ar;
} catch {
}
}
async void OnSignUpSignIn(object sender, EventArgs e)
{
try {
var ar = await App.PCApplication.AcquireTokenAsync(
AuthenticationInfo.Scopes, string.Empty, UiOptions.SelectAccount,
string.Empty, null, AuthenticationInfo.Authority,
AuthenticationInfo.SignUpSignInpolicy);
AuthenticationInfo.UserAuthentication = ar;
} catch (Exception ex) {
if (ex != null) {
}
}
}
and moved it to the ViewModel's OnNavigatedTo:
public async void OnNavigatedTo (NavigationParameters parameters)
{
if (parameters.ContainsKey ("title"))
Title = (string)parameters ["title"];
listen2asmr.App.PCApplication.PlatformParameters = platformParameters;
try {
var ar = await listen2asmr.App.PCApplication.AcquireTokenSilentAsync(
AuthenticationInfo.Scopes, string.Empty, AuthenticationInfo.Authority,
AuthenticationInfo.SignUpSignInpolicy, false);
AuthenticationInfo.UserAuthentication = ar;
} catch {
}
}
This is in the Bootstrapper:
protected override Xamarin.Forms.Page CreateMainPage ()
{
return Container.Resolve<LoginPage> ();
}
protected override void RegisterTypes ()
{
Container.RegisterTypeForNavigation<LoginPage>();
}
OnNavigatedTo never seems to get called though. Is there some other method I should be using, or did I miss something else? The only other thing I could think of was to call the code in OnNavigatedTo from the ViewModel constructor, but the async/await does work with the constructor.
This has been fixed in the latest preview version of Prism for Xamarin.Forms. Try using these packages instead:
https://www.nuget.org/packages/Prism.Forms/6.1.0-pre4
https://www.nuget.org/packages/Prism.Unity.Forms/6.2.0-pre4
Also the bootstrapping process has changed. Read this for more information:
Prism.Forms 5.7.0 Preview - http://brianlagunas.com/first-look-at-the-prism-for-xamarin-forms-preview/
Prism.Forms 6.2.0 Preview - http://brianlagunas.com/prism-for-xamarin-forms-6-2-0-preview/
Prism.Forms 6.2.0 Preview 3 - http://brianlagunas.com/prism-for-xamarin-forms-6-2-0-preview-3/
Preview 4 Post Coming Soon
My advice is use your View events as triggers for your ViewModel.
For Instance:
View.xaml.cs
protected override async void OnAppearing () {
base.OnAppearing ();
viewModel.OnAppearing();
}
async void OnSignUpSignIn(object sender, EventArgs e) {
viewModel.OnSignUpSignIn(sender, e);
}
ViewModel.cs
protected override async void OnAppearing () {
App.PCApplication.PlatformParameters = platformParameters;
try {
var ar = await App.PCApplication.AcquireTokenSilentAsync(
AuthenticationInfo.Scopes, string.Empty,
AuthenticationInfo.Authority,
AuthenticationInfo.SignUpSignInpolicy, false);
AuthenticationInfo.UserAuthentication = ar;
} catch {
}
}
async void OnSignUpSignIn(object sender, EventArgs e) {
try {
var ar = await App.PCApplication.AcquireTokenAsync(
AuthenticationInfo.Scopes, string.Empty,
UiOptions.SelectAccount,
string.Empty, null, AuthenticationInfo.Authority,
AuthenticationInfo.SignUpSignInpolicy);
AuthenticationInfo.UserAuthentication = ar;
} catch (Exception ex) {
if (ex != null) {
}
}
}
Reasons:
View should only involve visuals, and the events your page receives. Logic should be forwarded to the ViewModel, unless it deals with representation of information (for instance, logic to use a toggle-box for 2 choices but a combo-box for 3+).
Nearly vice-versa, the ViewModel should keep track of "model state" (ex. the user still needs to enter their payment information) as opposed to "view state" (ex. the user has navigated to the payment page).

Code to execute if a navigation fails

Hello I have no idea where I should start looking. I add few prop (before that my code run fine), then I get
System.Diagnostics.Debugger.Break();
so then I comment that changes, but that didn't help.
Could you suggest me where I should start looking for solution?
MyCode:
namespace SkydriveContent
{
public partial class MainPage : PhoneApplicationPage
{
private LiveConnectClient client;
FilesManager fileManager = new FilesManager();
// Constructor
public MainPage()
{
InitializeComponent();
}
private void signInButton1_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
infoTextBlock.Text = "Signed in.";
client.GetCompleted +=
new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.GetAsync("/me/skydrive/files/");
fileManager.CurrentFolderId = "/me/skydrive/files/";
}
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
void OnGetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
//Gdy uda nam się podłaczyc do konta skydrive
if (e.Error == null)
{
signInButton1.Visibility = System.Windows.Visibility.Collapsed;
infoTextBlock.Text = "Hello, signed-in user!";
List<object> data = (List<object>)e.Result["data"];
fileManager.FilesNames.Clear();
filemanager.filesnames.add("..");
foreach (IDictionary<string,object> item in data)
{
File file = new File();
file.fName = item["name"].ToString();
file.Type = item["type"].ToString();
file.Url = item["link"].ToString();
file.ParentId = item["parent_id"].ToString();
file.Id = item["id"].ToString();
fileManager.Files.Add(file);
fileManager.FilesNames.Add(file.fName);
}
FileList.ItemsSource = fileManager.FilesNames;
}
else
{
infoTextBlock.Text = "Error calling API: " +
e.Error.ToString();
}
}
private void FileList_Tap(object sender, GestureEventArgs e)
{
foreach (File item in fileManager.Files)
{
if (item.fName == FileList.SelectedItem.ToString() )
{
switch (item.Type)
{
case "file":
MessageBox.Show("Still in progress");
break;
case "folder":
fileManager.CurrentFolderId = item.ParentId.ToString();
client.GetAsync(item.Id.ToString() + "/files");
break;
default:
MessageBox.Show("Coś nie działa");
break;
}
}
else if (FileList.SelectedItem.ToString() == "..")
{
client.GetAsync(fileManager.CurrentFolderId + "/files");
}
}
}
}
}
Running stop at that line.
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
You should check all of the URLs you have both in the XAML and code. When you get to the NavigationFailed function, it means that the phone tried to navigate to some page that did not existed. We would be able to help more if you could tell what were you doing when the app threw the exception.
System.Diagnostics.Debugger.Break();
usually happens because of an Uncaught Exception.
Either post the code which started giving problems, or the stack trace when you encounter this problem.
No one can tell anything without actually seeing what you are doing.

Resources