如何在 ViewModel 中获取标签视图以在 xamarin 表单中设置可访问性焦点
How to get Label view in ViewModel to set accessibility focus in xamarin forms
我有 Label
视图,我需要 Label
在我的 ViewModel
视图中。我正在使用 Dependency Service 将重点放在 Controls for Accessibility 服务上,DS 需要 view
作为参数。
这是我的标签
<Label
AutomationProperties.IsInAccessibleTree="{Binding ShowNoResults}"
IsVisible="{Binding ShowNoResults}"
Text="{Binding ResultsHeader}"/>
我尝试了 Command
但 Label 不支持命令。下面的代码也不起作用
var view = GetView() as HomeworkView;
我总是 view
null
。我该如何解决这个问题?
我不太确定你想要实现什么,但你无法从你的视图模型中访问视图元素。
如果你想用控件做一些事情,你可以使用消息中心来做,这里有一个例子
在您的 ViewModel 中
MessagingCenter.Send(this, "your message here");
然后在您的页面中,您需要从该视图模型订阅此消息并执行所需的操作
MessagingCenter.Instance.Unsubscribe<ViewModelClassNamedel>(this, "your message here");
MessagingCenter.Instance.Subscribe<ViewModelClassName>(this, "your message here", (data) =>
{
this.youControlName.Focus();
});
更多详细信息已添加到 。
在您的 ViewModel 中(使用 class 名称“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 中清除它可能 cleaner/more 稳健。这确保它不会在页面不可见时使用(或在页面消失后的某些延迟操作中)。我可能会这样做。
protected override void OnAppearing()
{
base.OnAppearing();
((YourViewModel)BindingContext).ViewToFocus = this.yourLabelThatShouldBeFocused;
}
protected override void OnDisappearing()
{
((YourViewModel)BindingContext).ViewToFocus = null;
base.OnDisappearing();
}
我有 Label
视图,我需要 Label
在我的 ViewModel
视图中。我正在使用 Dependency Service 将重点放在 Controls for Accessibility 服务上,DS 需要 view
作为参数。
这是我的标签
<Label
AutomationProperties.IsInAccessibleTree="{Binding ShowNoResults}"
IsVisible="{Binding ShowNoResults}"
Text="{Binding ResultsHeader}"/>
我尝试了 Command
但 Label 不支持命令。下面的代码也不起作用
var view = GetView() as HomeworkView;
我总是 view
null
。我该如何解决这个问题?
我不太确定你想要实现什么,但你无法从你的视图模型中访问视图元素。
如果你想用控件做一些事情,你可以使用消息中心来做,这里有一个例子
在您的 ViewModel 中
MessagingCenter.Send(this, "your message here");
然后在您的页面中,您需要从该视图模型订阅此消息并执行所需的操作
MessagingCenter.Instance.Unsubscribe<ViewModelClassNamedel>(this, "your message here");
MessagingCenter.Instance.Subscribe<ViewModelClassName>(this, "your message here", (data) =>
{
this.youControlName.Focus();
});
更多详细信息已添加到
在您的 ViewModel 中(使用 class 名称“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 中清除它可能 cleaner/more 稳健。这确保它不会在页面不可见时使用(或在页面消失后的某些延迟操作中)。我可能会这样做。
protected override void OnAppearing()
{
base.OnAppearing();
((YourViewModel)BindingContext).ViewToFocus = this.yourLabelThatShouldBeFocused;
}
protected override void OnDisappearing()
{
((YourViewModel)BindingContext).ViewToFocus = null;
base.OnDisappearing();
}