【问题标题】:How to pass blank textbox value as null to binded datetime如何将空白文本框值作为空值传递给绑定的日期时间
【发布时间】:2023-03-28 17:00:02
【问题描述】:

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

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

文本框 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;
}

任何想法都会有所帮助。

【问题讨论】:

  • 据我所知,您的行 txtDueDateDetail.Text = null 永远不会起作用,因为 TextBox 的 text 属性永远不会为空。如果您立即读回该值,您会得到一个空字符串,而不是 null。我将尝试绑定不同的属性(例如 Tag),并在验证事件中更新该属性,但我在这里停下来,因为我不知道如何使用 EF。

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


【解决方案1】:

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

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

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

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

【讨论】:

【解决方案2】:

我无法绕过空日期时间验证,因此我关闭了字段 [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 的最佳解决方案。

【讨论】:

    【解决方案3】:

    我遇到了同样的问题并找到了这个解决方案。绑定由向 OnValidating 添加事件处理程序的函数控制。在此事件处理程序中,我们通过反射将底层实体属性设置为 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
    

    【讨论】:

      猜你喜欢
      • 2015-03-20
      • 2017-03-21
      • 2011-08-22
      • 1970-01-01
      • 2015-12-04
      • 1970-01-01
      • 2021-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多