问题描述
|
问候
我有一个绑定到实现INotifyDataErrorInfo的模型对象的Silverlight表单,并在单击“保存”按钮时进行了验证。如果模型上的某些属性返回无效,Silverlight将自动突出显示绑定的输入字段。
有没有办法将焦点设置到第一个无效字段?
更新:
甚至有办法查看输入字段是否处于该无效显示状态吗?如果可以检测到,可以遍历各个字段并手动设置焦点。
谢谢,
马修
解决方法
我已经实现了这种行为。
首先,您需要订阅ViewModel
ErrorsChanged
和PropertyChanged
方法。我在我的构造函数中这样做:
/// <summary>
/// Initializes new instance of the View class.
/// </summary>
public View(ViewModel viewModel)
{
if (viewModel == null)
throw new ArgumentNullException(\"viewModel\");
// Initialize the control
InitializeComponent(); // exception
// Set view model to data context.
DataContext = viewModel;
viewModel.PropertyChanged += new PropertyChangedEventHandler(_ViewModelPropertyChanged);
viewModel.ErrorsChanged += new EventHandler<DataErrorsChangedEventArgs>(_ViewModelErrorsChanged);
}
然后为该事件编写处理程序:
/// <summary>
/// If model errors has changed and model still have errors set flag to true,/// if we dont have errors - set flag to false.
/// </summary>
/// <param name=\"sender\">Ignored.</param>
/// <param name=\"e\">Ignored.</param>
private void _ViewModelErrorsChanged(object sender,DataErrorsChangedEventArgs e)
{
if ((this.DataContext as INotifyDataErrorInfo).HasErrors)
_hasErrorsRecentlyChanged = true;
else
_hasErrorsRecentlyChanged = false;
}
/// <summary>
/// Iterate over view model visual childrens.
/// </summary>
/// <param name=\"sender\">Ignored.</param>
/// <param name=\"e\">Ignored.</param>
private void _ViewModelPropertyChanged(object sender,PropertyChangedEventArgs e)
{
if ((this.DataContext as INotifyDataErrorInfo).HasErrors)
_LoopThroughControls(this);
}
最后添加方法:
/// <summary>
/// If we have error and we haven\'t already set focus - set focus to first control with error.
/// </summary>
/// <remarks>Recursive.</remarks>
/// <param name=\"parent\">Parent element.</param>
private void _LoopThroughControls(UIElement parent)
{
// Check that we have error and we haven\'t already set focus
if (!_hasErrorsRecentlyChanged)
return;
int count = VisualTreeHelper.GetChildrenCount(parent);
// VisualTreeHelper.GetChildrenCount for TabControl will always return 0,so we need to
// do this branch of code.
if (parent.GetType().Equals(typeof(TabControl)))
{
TabControl tabContainer = ((TabControl)parent);
foreach (TabItem tabItem in tabContainer.Items)
{
if (tabItem.Content == null)
continue;
_LoopThroughControls(tabItem.Content as UIElement);
}
}
// If element has childs.
if (count > 0)
{
for (int i = 0; i < count; i++)
{
UIElement child = (UIElement)VisualTreeHelper.GetChild(parent,i);
if (child is System.Windows.Controls.Control)
{
var control = (System.Windows.Controls.Control)child;
// If control have error - we found first control,set focus to it and
// set flag to false.
if ((bool)control.GetValue(Validation.HasErrorProperty))
{
_hasErrorsRecentlyChanged = false;
control.Focus();
return;
}
}
_LoopThroughControls(child);
}
}
}
, 您可以在视图中使用ValidationSummary来显示模型引发的所有验证错误。当您单击ValidationSummary中的错误时,引起验证错误的控件将集中显示。
在Silverlight工具包的示例中可以找到ValidationSummary的示例。
直到现在,我还没有在任何应用程序中使用ValidationSummary,因此我无法为您提供有关用法或“如何使用”的任何信息,但这也许会对您有所帮助