我正在开发具有各种弹出查找等的复杂数据输入表单。由于不同的事情 - 某些控件的焦点丢失了,我需要一些方法来设置 MVVM 中的焦点。到目前为止,我想出了我这样编码的附加属性(跳过了实际的依赖属性声明):
private static void SetFocus(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBox = d as TextBox;
if (textBox != null)
{
textBox.Focus();
}
}
所以,这很简单。当属性更改时 - 设置焦点。
我的观点:
<TextBox Text="{Binding CurrentItem.SerialNumber, Mode=TwoWay, NotifyOnValidationError=True}"
behaviors:TextBoxBehaviors.IsFocused="{Binding SecondaryControlFocus}"
Grid.Column="1" Grid.Row="2" Margin="1" Grid.ColumnSpan="2" TabIndex="2" />
如您所见 - 我附加了该行为并绑定(bind)到“SecondaryControlFocus”属性。
View 模型:
public bool SecondaryControlFocus
{
get
{
return this.secondaryControlFocus;
}
set
{
this.secondaryControlFocus = value;
this.RaisePropertyChanged(() => this.SecondaryControlFocus);
}
}
并编写我如何设置焦点的代码:
this.SecondaryControlFocus = !this.SecondaryControlFocus;
对我来说这个代码气味因为我必须切换属性力并返回才能触发属性..
有没有更好的方法来完成我的工作?当高级用户不能使用 TAB 键时,没有什么比这更令人恼火的了……而且我需要控制 MVVM 中的焦点,这对于正确的数据输入流程很重要。但我希望代码有点“好”
最佳答案
它确实有气味,但我认为我们对此无能为力
通常我对 AttachedProperty
做同样的事情。 , 并保留一个 IsFocused
View
中某处的 bool 值(因为这是一个特定于 View 的问题,不应与业务逻辑混在一起)。然后我会得到 View
为 EventAggregator
收听某种事件系统,例如(PRISM 的 Messenger
或 MVVM Light 的 ResetFocus
)事件,我会提出 ResetFocus
每当某些事情导致焦点在我的窗口/页面之间或在对话框之后发生变化时发生事件。
它不漂亮,但它有效。
关于Silverlight MVVM 和处理 FOCUS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7656015/