我在访问视图控制器.cs文件中的文本框时遇到问题
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);
}
在这个功能范围内,它抱怨它无法访问aynsc方法上的文本框
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");
});
}
这一行发生错误:
txtPassword.Text
错误如下:
UIKit.UIKitThreadAccessException:UIKit一致性错误:你是 调用只能从UI线程调用的UIKit方法。
即使密码正确,我的密码修正也不会显示。 我是否必须在单独的线程上运行UI警报?
答案 0 :(得分:13)
必须从UI线程(或主线程,主队列等)调用任何UIKit方法。这确保了UI的一致性。 Xamarin在调试模式下为所有UIKit方法添加了一个检查,如果您尝试使用后台线程来更改UI,则会抛出该异常。
解决方案很简单:只修改UI线程中的UI。这实际上意味着如果您使用的是" UI"在它前面,你应该从UI线程中做到这一点。 (这是一个经验法则,还有其他时间在UI线程上)。
如何在这个神秘的UI线程上获取我的代码?我很高兴你问。在iOS中,您有几个选择:
InvokeOnMainThread
将完成这一操作。CoreFoundation.DispatchQueue.MainQueue.DispatchAsync
始终有效。这两种方法都只接受Action
,可以是lambda或方法。
因此,在您的代码中,如果我们添加InvokeOnMainThread
(因为我认为这是在您的UIViewController
子类中)...
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.
InvokeOnMainThread(() => {
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");
});
}
答案 1 :(得分:1)
也许这对某人有帮助。因此,我将添加解决我的问题的方法,这与流氓相同。 在iOS中使用时,遵循避免xamarin表单一致性错误的代码
await Task.Run(async () =>
{
await Device.InvokeOnMainThreadAsync(async () =>
{
await MaterialDialog.Instance.SnackbarAsync(message: "Bla bla bla",
msDuration: MaterialSnackbar.DurationShort).ConfigureAwait(false);
}).ConfigureAwait(false);
}).ConfigureAwait(false);