更多细节添加到Mohammad's answer。
Message Center doc.
在您的 ViewModel 中(类名为“YourViewModel”):
// Here we use control name directly.
// OR could make an "enum" with a value for each control.
string controlName = ...;
MessagingCenter.Send<YourViewModel>(this, "focus", controlName);
然后在您的页面中,订阅此消息并执行所需的操作
.xaml.cs:
protected override void OnAppearing() {
{
base.OnAppearing();
// Unsubscribe before Subscribe ensures you don't Subscribe twice, if the page is shown again.
MessagingCenter.Instance.Unsubscribe<YourViewModel>(this, "focus");
MessagingCenter.Instance.Subscribe<YourViewModel>(this, "focus", (controlName) =>
{
View v = null;
switch (controlName) {
case "name1":
v = this.name1;
break;
case "name2":
v = this.name2;
break;
}
if (v != null) {
//v.Focus();
// Tell VM to use v as view.
((YourViewModel)BindingContext).SetFocus(v);
}
});
}
protected override void OnDisappearing() {
MessagingCenter.Instance.Unsubscribe<YourViewModel>(this, "focus");
base.OnDisappearing();
}
如果需要将View v 传递回VM,因为那有使用它的逻辑:
public class YourViewModel
{
public void SetFocus(View view)
{
... your code that needs label's view ...
}
}
未测试。可能需要一些细微的改变。可能需要
...(this, "focus", (sender, controlName) =>
而不是
...(this, "focus", (controlName) =>
更新
简单的方法,如果 VM 中只需要一个视图。
public class YourViewModel
{
public View ViewToFocus { get; set; }
// The method that needs ViewToFocus.
void SomeMethod()
{
...
if (ViewToFocus != null)
... do something with it ...
}
}
public class YourView
{
public YourView()
{
InitializeComponent();
...
// After BindingContext is set.
((YourViewModel)BindingContext).ViewToFocus = this.yourLabelThatShouldBeFocused;
}
}
替代方案:在页面的 OnAppearing 中设置 ViewToFocus 并在 OnDisappearing 中清除它可能会更清晰/更健壮。这确保了在页面不可见时(或页面消失后的某些延迟操作)永远不会使用它。我可能会这样做。
protected override void OnAppearing()
{
base.OnAppearing();
((YourViewModel)BindingContext).ViewToFocus = this.yourLabelThatShouldBeFocused;
}
protected override void OnDisappearing()
{
((YourViewModel)BindingContext).ViewToFocus = null;
base.OnDisappearing();
}