C# 如何将空白文本框值作为null传递给绑定的datetime

C# 如何将空白文本框值作为null传递给绑定的datetime,c#,winforms,entity-framework,data-binding,C#,Winforms,Entity Framework,Data Binding,根据标签,这是一个实体框架,C#,Winforms问题 我将文本框数据绑定到实体中可为空的日期时间字段。当我删除文本框的内容并将其保留为空时,我希望将空值传递回实体 Textbox CausesValidation属性=true。当我删除文本框的内容时,如果不输入有效日期,我将无法离开它 这是我的验证事件 private void txtDueDateDetail_Validating(object sender, CancelEventArgs e) { string errorMsg

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

我将文本框数据绑定到实体中可为空的日期时间字段。当我删除文本框的内容并将其保留为空时,我希望将空值传递回实体

Textbox CausesValidation属性=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;
}

任何想法都会有帮助。

我无法绕过空日期时间验证,因此我关闭了[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);

    }

功能性。。。但这不是最好的解决方案。

我无法绕过空日期时间验证,因此我关闭了[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);

    }

功能性。。。但在我看来,这不是最好的解决方案。

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

txtDueDateDetail.DataBindings["Text"].NullValue = "";
根据,将空字符串分配给
NullValue
与分配
null
(这是其默认值)不同


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

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

txtDueDateDetail.DataBindings["Text"].NullValue = "";
根据,将空字符串分配给
NullValue
与分配
null
(这是其默认值)不同


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

我也遇到了同样的问题,并找到了这个解决方案。绑定由一个函数控制,该函数向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

我也遇到了同样的问题,并得出了这个解决方案。绑定由一个函数控制,该函数向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

据我所知,您的行txtdudedatedetail.Text=null永远不会工作,因为TextBox的Text属性永远不会为null。如果您立即读回该值,则会得到一个空字符串,而不是null。我将尝试绑定一个不同的属性(例如标记),并在验证事件中更新该属性,但我在这里停止,因为我不知道如何使用EF。正如我所知,您的行txtDueDateDetail.Text=null永远不会工作,因为TextBox的文本属性永远不会为null。如果您立即读回该值,则会得到一个空字符串,而不是null。我将尝试绑定一个不同的属性(例如标签),并在验证事件中更新该属性,但我在这里停止,因为我不知道如何使用EF。谢谢您的帖子。我也偶然发现了这本书。如果我需要编辑这个部分,我会看看是否可以使用上面的解决方案。谢谢你的帖子。我也偶然发现了这本书。如果我需要编辑此部分,我将查看是否可以使用上述解决方案。