Silverlight:SetTextBoxFocusUsingMVVM






4.80/5 (12投票s)
如何在验证时使用 MVVM 模式在文本框中设置焦点。
引言
MVVM 是微软的一种架构模式。View 类不知道模型是否存在,但是 viewmodel 和模型不知道 view。它是一种松耦合设计。
这样可以区分设计师的角色,使其专注于 UI 而不是编程/业务逻辑,并允许应用程序在不同的工作流程中工作。
如果有兴趣,请在 Silverlight 中 MVVM 的 5 分钟概述 中获取更多详细信息。
本文解释了在使用 MVVM 模式时,如何在 textbox
(View) 中使用验证逻辑来设置焦点的问题。
背景
我的一个朋友给了我一个问题并要求我提供一个解决方案,我觉得大多数开发人员都需要它,所以我决定写一篇关于此的文章,这可能会有所帮助。
通常情况下,应用程序有一些控件 (Textbox
) 需要最终用户的输入,并且当最终用户执行某些操作(保存或移动到另一个表单)时,我们会在按钮点击时进行验证。现在在 Silverlight 中,借助 ValidatesOnDataErrors=True 属性,显示 UI,textbox
外面有一个红色边框,表明必填字段/无效数据。您可以在下面的屏幕 1 和屏幕 2 中看到。
但是,如果光标在 textbox
内部闪烁会更好,这样用户就不需要显式地单击鼠标以在 textbox
内部设置焦点,之后他/她才能输入。
因此,这里的兴趣点是在不编写任何 View 代码隐藏文件的情况下,使用 MVVM 模型来实现这一点。
下面的屏幕 3 解释了更多
Using the Code
目前 Silverlight 4.0 没有直接提供 CommandManager
,借助如何 在 Silverlight 2 中创建命令管理器,因为此命令管理器将在 View 中实现,它会将按钮的命令与点击事件绑定。
<Button Content="Click!"="3"Grid.Column="2"Grid.ColumnSpan="2"
Cmd:CommandManager.CommandEventName="Click"
Cmd:CommandManager.Command="{Binding ClickCommand }" />
目前,此 CommandManager
是作为单独的库创建的,可以在任何其他 Silverlight 类库中使用。
类 TextBoxAttach
现在定义一个类名 TextBoxAttach,它具有 Dependency
属性 (TextBoxControllerProperty)。此属性注册一个函数 OnTextBoxControllerChanged,该函数将在 textbox
控件加载时执行。以下代码中的重点是,当此属性附加到 textbox
时,它会定义一个名为 elements1
的字典,该字典将 textbox
名称存储为 ID
。
private static readonly Dictionary<string,TextBox> elements1 =
new Dictionary<string,TextBox>();
private static void OnTextBoxControllerChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as TextBox;
if (element == null)
throw new ArgumentNullException("d");
var newController = e.NewValue as ITextBoxController;
if (newController != null)
{
elements1.Add(element.Name, element);
newController.ClickButton += ClickButton;
}
}
现在,当您单击按钮时,会触发 ClickButton 事件,该事件会检查 textbox
是否为空,以及那些已附加 TextBoxControllerProperty 的 textbox
,并且它将在 textbox
内部设置焦点。
private static void ClickButton(ITextBoxController sender)
{
foreach (KeyValuePair<string,TextBox> pair in elements1)
{
TextBox element;
string key = pair.Key;
element = pair.Value;
if (string.IsNullOrEmpty(element.Text))
{
element.Focus();
break;
}
}
}
因此,要使用此 TextBoxAttach
在 textbox
内部设置焦点,XAML 代码将如下所示
<TextBox x:Name="textBox1" loc:TextBoxAttach.TextBoxController="{Binding}" />
类 MyViewModel
类 MyViewModel 继承自 ITextBoxController 并使用 ClickEventhandler 事件,该事件在 ITextBoxController 中定义。并且在这里,在 MyViewModel 的构造函数中,借助 RelayCommand 初始化 ClickCommand,RelayCommand 本身继承自 ICommand。
public MyViewModel()
{
Value1 = "My Text1";
Value2 = "My Text2";
ClickCommand = new RelayCommand(p =>
{
if (ClickButton != null)
ClickButton(this);
});
}
现在为了在 view 中显示验证错误 UI,MyViewModel 类还继承自 IDataErrorInfo,它实现了索引器,也称为 C# 中的智能数组。它非常像定义属性
public string this[string columnName]
{
get
{
string strMessage = string.Empty;
CustomValidation(ref strMessage, columnName);
return strMessage;
}
}
要使用此验证功能,XAML 代码将如下所示
<TextBox x:Name="textBox1" Text="{Binding Path=Value1,
Mode=TwoWay,ValidatesOnDataErrors=True}" />
关注点
最后
由于总有改进的空间,如果您有任何意见/投诉/建议,请告诉我。我将尝试解决这些问题,您的反馈将帮助我改进未来在 CodeProject J 上的文章。
历史
- 发布于 2010 年 9 月 18 日