如何将空白文本框值作为null传递给绑定日期时间

时间:2012-03-22 20:36:11

标签: c# winforms entity-framework data-binding

根据标签,这是一个实体框架,C#,Winforms问题。

我有一个文本框数据绑定到我的实体中可以为空的datetime字段。我想在删除文本框的内容时将空值传回实体,并将其留空。

Textbox CausesValidation property = true。当我删除文本框的内容时,如果没有输入有效日期,我将无法离开。

这是我的验证活动

private void txtDueDateDetail_Validating(object sender, CancelEventArgs e)
{
    string errorMsg;
    if (!ValidDate(txtDueDateDetail.Text, out errorMsg))
    {
        // Cancel the event and select the text to be corrected by the user.
        e.Cancel = true;
        txtDueDateDetail.Select(0, txtDueDateDetail.Text.Length);

        // Set the ErrorProvider error with the text to display. 
        this.epNew.SetError(txtDueDateDetail, errorMsg);
    }

    Debug.Write("text: " + txtDueDateDetail.Text);
}

public bool ValidDate(string pTextDate, out string errorMessage)
{
    DateTime tempDate;
    errorMessage = "";

    if (pTextDate.Length == 0)
    {
        //pass a null date...how?
        return true;
    }

    DateTime.TryParse(pTextDate, out tempDate);
    if (tempDate == DateTime.MinValue)
    {
        errorMessage = "date must be in format MM/dd/yyyy";
        return false;
    }

    return true;
}

任何想法都会有所帮助。

3 个答案:

答案 0 :(得分:3)

考虑到您的初始方法,您是否尝试将Binding.NullValue设置为空字符串?您可以按以下方式以编程方式执行此操作:

txtDueDateDetail.DataBindings["Text"].NullValue = "";

根据docs,将空字符串分配给NullValue与分配null(这是默认值)不同。

你的最终解决方案没问题。在我阅读NullValue属性之前,我考虑过实现它。对我来说,它的缺点是它会降低数据绑定的实用性,因为这样我最终会手动将更改后的值分配回数据源 - 我希望数据绑定能够为我做这件事。

答案 1 :(得分:1)

我无法绕过null日期时间验证,所以我关闭了[CausesValidation = FALSE]字段的验证并在Leave事件中执行了我自己的验证。

 public bool ValidDate(string pTextDate, out DateTime? pDate, out string errorMessage)
    {
        DateTime tempDate;
        errorMessage = "";
        pDate = null;
        if (pTextDate.Length == 0)
        {
            //pass null date here...
            return true;
        }
        DateTime.TryParse(pTextDate, out tempDate);

        if (tempDate == DateTime.MinValue)
        {
            errorMessage = "date must be in format MM/dd/yyyy";
            return false;
        }
        pDate = tempDate;
        return true;
    }

    private void txtDueDateDetail_Leave(object sender, EventArgs e)
    {
        string errorMsg;
        DateTime? outDate;
        if (!ValidDate(txtDueDateDetail.Text, out outDate, out errorMsg))
        {
            txtDueDateDetail.Select(0, txtDueDateDetail.Text.Length);
        }
        else
        {
            int CID = Convert.ToInt32(txtChargebackIDDetail.Text);
            var temp = (from c in chg.ChargeBackks
                        where c.ID == CID
                        select c).FirstOrDefault();
            temp.DueDate = outDate;
        }
        this.epNew.SetError(txtDueDateDetail, errorMsg);

    }

功能......但不是IMO的最佳解决方案。

答案 2 :(得分:0)

我遇到了同样的问题,并提出了解决方案。绑定由向OnValidating添加事件处理程序的函数控制。通过反思,在此事件处理程序中,我们将基础实体属性设置为null或文本框中的值。这是允许通过验证的密钥-您必须将基础实体字段设置为null。即使处理e.Cancel也无济于事。

对绑定的调用如下:

AddDateBinding(Me.txtPhantomBlockIrrDate, Me.bsPhantomBlock, "IRRADIATE_DATE")

  Public Sub AddDateBinding(control As Control, bs As BindingSource, field As String)
        Dim controlProperty As String = ""

        If TypeOf (control) Is TextBox Then
            controlProperty = "Text"
        End If
        If TypeOf (control) Is ComboBox Then
            controlProperty = "SelectedValue"
        End If

        control.DataBindings.Add(New System.Windows.Forms.Binding(controlProperty, bs, field, True, DataSourceUpdateMode.OnValidation, Nothing, "MM/dd/yyyy"))
        AddHandler control.Validating, AddressOf DateValidating

    End Sub

    Public Sub DateValidating(sender As Object, e As System.ComponentModel.CancelEventArgs)
        e.Cancel = False
        Try
            If CType(sender, Control).Text = "" Then
                e.Cancel = False
                Dim fieldName As String = CType(sender, Control).DataBindings(0).BindingMemberInfo.BindingField
                Dim bs As BindingSource = CType(CType(sender, Control).DataBindings(0).DataSource, BindingSource)
                Dim propInfo As Reflection.PropertyInfo = bs.Current.GetType().GetProperty(fieldName)
                propInfo.SetValue(bs.Current, Nothing, Nothing)
            Else
                e.Cancel = False
                Dim fieldName As String = CType(sender, Control).DataBindings(0).BindingMemberInfo.BindingField
                Dim bs As BindingSource = CType(CType(sender, Control).DataBindings(0).DataSource, BindingSource)
                Dim propInfo As Reflection.PropertyInfo = bs.Current.GetType().GetProperty(fieldName)
                propInfo.SetValue(bs.Current, CType(sender, Control).Text, Nothing)
            End If

        Catch ex As Exception

        End Try
    End Sub