无法逃脱空文本框 [英] Can't escape empty textbox

查看:75
本文介绍了无法逃脱空文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试查找最近从VS2003升级到VS2008的应用程序中令人讨厌的界面错误的原因(该错误在迁移前不存在). 这是怎么回事:

I'm trying to track down the cause of an annoying interface bug in an app that was recently upgraded from VS2003 to VS2008 (the bug did not exist pre-migration). What happens is this :

1)用户单击包含日期的文本框.
2)用户清除日期
3)用户尝试移动到另一个字段,但不能移动.没有错误消息出现-好像验证失败.

1) User clicks in textbox containing a date.
2) User clears date
3) User tries to move to another field, but can't. No error messages appear - it's as if the validation failed.

更多信息:

1)文本框的Text属性绑定到使用数据表作为源的数据视图. bound字段是可为空的datetime字段,没有任何约束或默认值.
2)触发Validating事件,并且CancelEventArgs属性未设置为Cancel. Validated,LostFocus和Leave事件也都触发,进入LostFocus> Leave> Validating
3)我看不到与控件或数据源相关的任何代码更改,但有一些例外.首先是:

1) The textbox's Text property is bound to a dataview which uses a datatable as its source. The bound field is a nullable datetime field with no constraints or default.
2) The Validating event fires and the CancelEventArgs property is not set to Cancel. The Validated, LostFocus and Leave events all fire as well, going LostFocus > Leave > Validating
3) I can't see any code changes relating to the control or the datasource with a couple of exceptions. The first is that this :

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd"))

现在已更改为此:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))

第二个是这个:

Me.dcolRangeEnd.DataType = GetType(System.DateTime)

现在已更改为此:

Me.dcolRangeEnd.DataType = GetType(Date)

还有这一点,从第一天开始就已经存在于代码中:

There is also this, which has been in the code since day one :

AddHandler txtRangeEnd.DataBindings("Text").Format, AddressOf FormatBoxToDate

Private Sub FormatBoxToDate(ByVal sender As Object, ByVal e As ConvertEventArgs)
Try
    If Not e.Value Is DBNull.Value Then
            e.Value = Format(e.Value, "d")
        End If
    End Try
End Sub

现在,如果我从添加数据绑定中删除了"True",那么我可以使用空白值退出控件,但是它将恢复为原始值.删除日期格式似乎对此没有任何影响(它只是恢复为显示06/01/2011 00:00:00,而不是所需的06/01/2010).没有其他代码完全引用该文本框.我在想在VS2003和VS2008之间的数据绑定控件的验证中必须进行一些更改,但是很可能我缺少了一些令人震惊的显而易见的内容.

Now, if I remove the ", True" from the adding of the databinding then I can exit the control with a blank value, but it then reverts to the original value. Removing the date formatting appears to make no difference to this (it just reverts to showing 06/01/2011 00:00:00 rather than the desired 06/01/2010). No other code refers to that textbox at all. I'm thinking something must have changed in validation of databound controls between VS2003 and VS2008, but it's just as likely I'm missing something mind-numbingly obvious.

有什么想法吗?

推荐答案

看到此行为的原因与Windows Forms及其数据绑定如何处理NULL数据库值有关.

The reason that you're seeing the observed behaviour is to do with how Windows Forms and it's Data Binding handles NULL database values.

TL; DR 原因:

The TL;DR reason:

请参阅以下Microsoft Connect建议:

See this Microsoft Connect suggestion: Provide better databinding support for nullable types

长版:

本质上发生的是,当您清除文本框(为空字符串)并随后将其制表符移开时,绑定会将您的空字符串转换为

What is essentially happening is that as you clear the Textbox (to an empty string) and subsequently tab away, the binding is converting your empty string to a DBNull value which is then propagated to the data source however the binding, since it is two-way, then attempts to re-populate the bound control (the Textbox) with appropriate formatting, and fails, causing the Textbox to display the strange behaviour of not allowing the focus to be removed from it!

由于 DataSourceNullValue 绑定类的属性.可以使用Binding类的构造函数重载之一进行设置,也可以通过属性设置单独进行设置,但是,如果您未显式设置此属性,则需要注意以下几点:

This is happening due to the DataSourceNullValue property of the Binding class. This can be set using one of the Binding classes constructor overloads, or set separately via a property setting, however, if you do not explicitly set this property, it is important to note that:

值类型的默认值为DBNull 对于非值类型则为null.

The default is DBNull for value types and null for non-value types.

您似乎没有明确设置此项,因此默认设置是应用,并且DateTime为

It appears that you're not explicitly setting this, so the default is applying, and with your DateTime being a value type, it is using DBNull.

一旦数据源已更新(到DBNull),绑定机制将尝试使用新近更新的数据源值重新填充文本框.当基础数据源值为DBNull时,用于绑定控件的值由Binding类的

Once the data source has been updated (to DBNull), the binding mechanism will attempt to then repopulate the Textbox with the newly updated data source value. When the underlying data source value is DBNull, the value used for the bound control is governed by the Binding class's NullValue property. Again, if this property is not explicitly set either via the relevant overloaded constructor argument or via the property setting itself, the default value will apply, which is:

要设置为控件的对象 数据源包含时的属性 DBNull值. 默认为空.

The Object to be set as the control property when the data source contains a DBNull value. The default is null.

当然,文本框的Text属性只能设置为 System.String 而不是null值(在VB中为Nothing),因此TextBox无法将数据源值(DBNull)的代表值(null/nothing)绑定到绑定的控件.

Of course, a Textbox's Text property can only be set to an object of type System.String and not a null value (Nothing in VB), so the TextBox fails to bind the representative value (null/nothing) of the data source's value (DBNull) to the bound control.

纠正此行为的方法是确保

The way to correct this behaviour is to ensure that the Binding class's NullValue property is explicitly set to a suitable value. In this case, a zero-length string will suffice to correct the problem.

实现此目的的一种方法是更改​​行:

One way to achieve this is to change the line:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))

收件人:

Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True, DataSourceUpdateMode.OnValidation, ""))

这里的键是最后一个参数,它是NullValue,它设置为零长度的字符串(

The key here is the very last parameter, which is the NullValue, set to a zero-length string (The DataSourceUpdateMode is also explicitly specified due to the arguments of the constructor, but it's being set to it's default value anyway).

尽管所有这些,但它似乎不是某种奇怪的"行为,即使它不是实际的错误也是如此.其他似乎也遇到相同问题的人(在Visual Studio 2010/.NET 4.0中仍然很普遍!)也证明了这一点. 此线程在social.msdn.microsoft.com论坛上,有人遇到了相同的问题,并给出了一些有趣的解释,说明了为什么会发生这种情况以及Microsoft为什么以此方式进行设计.

Despite all of this, it does appear to be somewhat "odd" behaviour, if not an actual bug. This is also evidenced by others who appear to be experiencing the same issue (which is still prevalent in Visual Studio 2010/.NET 4.0!). This thread on the social.msdn.microsoft.com forums contains someone experiencing the same issue with some interesting possible explanations as to why this happens, and why Microsoft designed it this way.

还有一个早在2005年就报告了Microsoft Connect建议,该建议着重指出了该问题.此建议已被如已关闭".似乎Microsoft并不认为它是一个错误,因为存在一个非常合理的解决方法(绑定的NullValue属性的显式设置),可以说,出于可读性考虑,无论如何都应这样做.他们显然会在将来考虑该建议.

There is also a Microsoft Connect suggestion that was reported back in 2005 that highlights the issue. This suggestion has been "Closed as Postponed". It appears that Microsoft do not consider it a bug, as a very reasonable workaround exists (the explicit setting of the Binding's NullValue property) which, arguably, should be done anyway for readability's sake. They will apparently consider the suggestion in the future.

返回到为什么在.NET 2.0之前(Visual Studio 2005)不存在此问题的原因似乎是由于整个数据绑定机制针对.NET Framework 2.0的发布而进行了彻底修改.您最初的解决方案是VS2003项目,当时使用的是.NET Framework 1.1,它没有这么丰富的数据绑定功能集.尽管我不再拥有VS2003的副本来进行测试,但是我假设.NET 1.1中的绑定机制更多地使用了控件值和数据源值之间的隐式转换.当您从 受支持. aspx"rel =" noreferrer>.NET 1.1 ,与

Going back to why this didn't exist pre-.NET 2.0 (Visual Studio 2005) seems to be due to the fact that the entire data binding mechanism was completely revamped for the release of .NET Framework 2.0. Your original solution, being a VS2003 project was using .NET Framework 1.1 which did not have as rich a data binding feature-set. Although I no longer have a copy of VS2003 to hand to test this, I'm assuming the binding mechanism in .NET 1.1 made much more use of implicit conversions between the control's value and the data source's value. This appears to be supported when you examine the Binding class from .NET 1.1, compared with .NET 2.0 (or higher). For example, there was no way to (easily) control the actual two-way binding itself (and how values are converted between the form and the data source) or the formatting of said values.

这篇关于无法逃脱空文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆