I am having a issue accesing a text box in a view controller .cs file
async partial void loginUser(UIButton sender)
{
// Show the progressBar as the MainActivity is being loade
Console.WriteLine("Entered email : " + txtEmail.Text);
// Create user object from entered email
mCurrentUser = mJsonHandler.DeserialiseUser(txtEmail.Text);
try
{
Console.WriteLine("Starting network check");
// Calls email check to see if a registered email address has been entered
if (EmailCheck(txtEmail.Text) == true)
{
await CheckPassword();
}
else
{
UIAlertView alert = new UIAlertView()
{
Title = "Login Alert",
Message = "Incorrect email or password entered"
};
alert.AddButton("OK");
alert.Show();
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("An error has occured: '{0}'", ex);
}
It is within this funciton that it complains it cannot access a text box which is on a aynsc method
public Task CheckPassword()
{
return Task.Run(() =>
{
// Creates instance of password hash to compare plain text and encrypted passwords.
PasswordHash hash = new PasswordHash();
// Checks password with registered user password to confirm access to account.
if (hash.ValidatePassword(txtPassword.Text ,mCurrentUser.password)==true)
{
Console.WriteLine("Password correct");
UIAlertView alert = new UIAlertView()
{
Title = "Login Alert",
Message = "Password Correct Loggin In"
};
alert.AddButton("OK");
alert.Show();
//insert intent call to successful login here.
}
else
{
UIAlertView alert = new UIAlertView()
{
Title = "Login Alert",
Message = "Incorrect email or password entered"
};
alert.AddButton("OK");
alert.Show();
}
Console.WriteLine("Finished check password");
});
}
Its this line the error occurs:
txtPassword.Text
The error is as follows:
UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.
Also my Password Correct does not show even though if it is a correct password. Do i have to run the UI Alerts on a seperate thread?
Any UIKit methods must be called from the UI thread (or Main thread, Main queue, etc.). This ensures consistency in the UI. Xamarin adds a check to all UIKit methods in debug mode and throws that exception if you try to use a background thread to change the UI.
The solution is simple: only modify the UI from the UI thread. That essentially means if you're using a class with "UI" in front it, you should probably do it from the UI thread. (That's a rule of thumb and there are other times to be on the UI thread).
How do I get my code on this mythical UI thread? I'm glad you asked. In iOS, you have a few options:
InvokeOnMainThread
will do the trick.CoreFoundation.DispatchQueue.MainQueue.DispatchAsync
will always work.Both of those methods just accept an
Action
, which can be a lambda or a method.So in your code, if we add an
InvokeOnMainThread
(because I think this is in yourUIViewController
subclass)...