2014-06-27 111 views
2
private void StartDate_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (!validate()) 
    { 
     Dispatcher.BeginInvoke(
     DispatcherPriority.ContextIdle, 
     new Action(delegate() 
     { 
      StartDate.Focus(); 
     }) 
    }); 
} 

我正在验证WPF应用程序的文本框丢失焦点中的日期。目前,我做了一些日期验证 - 如果验证失败,我将焦点重置到文本框。这是正确的方法吗?WPF窗体验证

它似乎工作正常,我希望我不创建任何问题或内存泄漏与BeginInvoke。

在此先感谢

+0

这个工程,但没有多大意义,对我来说。您正在同步执行UI线程中的实际验证(阻塞UI线程),然后您将焦点移至BeginInvoke(仍为UI线程,但是是异步)的StartDate控件。你确定这是你的目标吗? –

+0

我想说的是,由于您已经在UI线程中同步验证,所以没有必要异步执行Focus()方法。在UI线程中也是如此。我会建议做的异步验证(用户界面或,最好在不同的线程),然后在UI线程中同步设置焦点。 –

+1

我推荐看看['IDataErrorInfo'](http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo.aspx)和['INotifyDataErrorInfo'](http:// msdn。 microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(v=vs.110).aspx)以获得更多标准的WPF验证方法。 –

回答

0

ADI公司建议,请考虑使用更常见的方法进行验证。但是,如果你正在工作的应用程序的东西只是为了好玩,或只是去了解WPF是如何工作的,请考虑:

  1. 验证异步
  2. 同步在UI线程与UI交互

此外,失去焦点之前验证(TextChanged可能是一个选项)。这样的事情:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBox validatedTextbox = sender as TextBox; 
     validatedTextbox.IsEnabled = false; 

     BackgroundWorker worker = new BackgroundWorker(); 

     worker.DoWork += (s, ea) => { Thread.Sleep(1000); }; // just to simulate really long validation 
     worker.RunWorkerCompleted += (s, ea) => 
     { 
      if (validatedTextbox.Text.Contains('a')) 
      { 
       validatedTextbox.Background = new SolidColorBrush(Colors.Red); 
      } 
      else 
      { 
       validatedTextbox.Background = new SolidColorBrush(Colors.Green); 
      } 

      validatedTextbox.IsEnabled = true; 
     }; 

     worker.RunWorkerAsync(); 
    } 
+0

谢谢你的回复。我选择了lostCocus而不是textChange事件,因为我认为这个验证会在每个关键笔画上触发...也就是说,对于今天 - 0 validate()6 validate()2 validate()8 validate()等。是否有任何问题接着就,随即? –

+0

我不这么认为,真的。那么,答案是非常具体的你的验证的上下文,例如它如何影响用户体验,所以你必须自己回答。然而,从纯粹的技术角度来看,这就是验证应该工作的方式 - 在幕后进行验证,然后在UI线程中更新UI。我相信这是你的原始问题。 –

+0

谢谢你的帮助。 –