加载新视图时,我需要关注特定的文本框。
解决方案是将这行代码添加到视图的 OnLoaded 事件中:
Dispatcher.BeginInvoke(() => { NameTextBox.Focus(); });
所以这适用于一种观点,但不适用于另一种观点。我花了一些时间调试这个问题,并意识到我正在处理的新视图有一个 BusyIndicator,因为 BusyIndicator 设置为 true 和 false 是在 OnLoaded 事件之后发生的,所以它会将焦点从所有控件上移开。
所以解决方案是在我的 BusyIndicator 设置为 falseNameTextBox
之后调用焦点。我的想法是创建一个可重用的 BusyIndicator 控件来处理这些额外的工作。但是,我在 MVVM 中遇到了麻烦。
我首先对工具包进行了简单的扩展:BusyIndicator:
public class EnhancedBusyIndicator : BusyIndicator
{
public UserControl ControlToFocusOn { get; set; }
private bool _remoteFocusIsEnabled = false;
public bool RemoteFocusIsEnabled
{
get
{
return _remoteFocusIsEnabled;
}
set
{
if (value == true)
EnableRemoteFocus();
}
}
private void EnableRemoteFocus()
{
if (ControlToFocusOn.IsNotNull())
Dispatcher.BeginInvoke(() => { ControlToFocusOn.Focus(); });
else
throw new InvalidOperationException("ControlToFocusOn has not been set.");
}
我将控件添加到我的 XAML 文件中没有问题:
<my:EnhancedBusyIndicator
ControlToFocusOn="{Binding ElementName=NameTextBox}"
RemoteFocusIsEnabled="{Binding IsRemoteFocusEnabled}"
IsBusy="{Binding IsDetailsBusyIndicatorActive}"
...
>
...
<my:myTextBox (this extends TextBox)
x:Name="NameTextBox"
...
/>
...
</my:EnhancedBusyIndicator>
所以想法是当IsRemoteFocusEnabled
在我的 ViewModel 中设置为 true (我在 ViewModel 中设置IsBusy
为 false 之后执行此操作),焦点将设置为NameTextBox
. 如果它有效,其他人可以使用EnhancedBusyIndicator
并绑定到不同的控件,并在他们自己的 ViewModel 中适当地启用焦点,假设他们的视图具有初始BusyIndicator
活动状态。
但是,加载视图时出现此异常:
设置属性 'foo.Controls.EnhancedBusyIndicator.ControlToFocusOn' 引发异常。[行:45 位置:26]
我正在尝试的这个解决方案会起作用吗?如果是这样,到目前为止我所拥有的有什么问题(无法设置ControlToFocusOn
属性)?
更新 1
我为 Silverlight 5 安装了 Visual Studio 10 工具,并在导航到新视图时收到了更好的错误消息。现在我收到此错误消息:
“System.ArgumentException:System.Windows.Data.Binding 类型的对象无法转换为 System.Windows.Controls.UserControl 类型”
另外,我认为我需要更改此控件的 DataContext。在代码隐藏构造函数中,DataContext 设置为我的 ViewModel。我尝试将 DataContext 属性添加到EnhancedBusyIndicator
,但这不起作用:
<my:EnhancedBusyIndicator
DataContext="{Binding RelativeSource={RelativeSource Self}}"
ControlToFocusOn="{Binding ElementName=NameTextBox}"
RemoteFocusIsEnabled="{Binding IsRemoteFocusEnabled}"
IsBusy="{Binding IsDetailsBusyIndicatorActive}"
...
>
更新 2
我需要更改UserControl
为,Control
因为我想将焦点设置为TextBox
对象(实现Control
)。但是,这并不能解决问题。