You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨窗体调用UserControl数据保存至数据库空值异常求助

问题:主窗体按钮触发UserControl保存数据为空,内部按钮正常

问题描述

通过主窗体的Save按钮触发UserControl中的数据保存到数据库,主窗体已嵌入该UserControl且包含Save按钮。代码运行无报错,但数据库存入的是空值;将Save按钮放置在UserControl内部时,功能完全正常。

相关代码

窗体代码(原错误代码)

namespace REMAS.Forms.Account
{
    public partial class frmCreateFixedAssetCategories : Form
    {
        SqlConnection conn = new SqlConnection("Server=localhost;Database=TESTCRUD;User Id=sa;Password=123456");
        SqlCommand cmd;
        SqlDataAdapter adapter;
        SqlDataReader reader;
        DataTable dt;
        string sql, sAction;
        int iID;
        private uctInformation uctInformationInstance;
        public frmCreateFixedAssetCategories()
        {
            InitializeComponent();
            uctInformationInstance = new uctInformation();
            // Assuming you have a panel or some container to host the UserControl
        }

        private void btnSaveActions_Click(object sender, EventArgs e)
        {
            uctInformationInstance.savedata();
        }
    }
}

UserControl代码

namespace REMAS.Forms.Purchase
{
    public partial class uctInformation : UserControl
    {
        SqlConnection conn = new SqlConnection("Server=localhost;Database=TESTCRUD;User Id=sa;Password=123456");
        SqlCommand cmd;
        SqlDataAdapter adapter;
        SqlDataReader reader;
        DataTable dt;
        string sql, sAction;
        int iID;
        public uctInformation()
        {
            InitializeComponent();
        }

        private void uctInformation_Load(object sender, EventArgs e)
        {
            ClearText();
        }

        void ClearText()
        {
            txbAddresses.Clear();
            txbFixedPhone.Clear();
            txbFaxuctInf.Clear();
            txbMobileuctInf.Clear();
            txbEmailuctInf.Clear();
            txbWebuctInf.Clear();
            txbRegCode.Clear();
            txbTaxN.Clear();
            txbLanguageuctInf.Clear();
            txbAccOwner.Clear();
            txbTeamuctInf.Clear();
            cmbCategoryuctInf.Items.Clear();
            cmbIndustryuctInf.Items.Clear();
            cmbSourceuctInf.Items.Clear();
            cmbDeptuctInf.Items.Clear();
            cmbCompaniesAssoci.Items.Clear();
            nudTurnoveructInf.Value = 0;
            nudEmployeesuctInf.Value = 0;
            nudPaymentuctInf.Value = 0;
            rtbNotes.Clear();
        }

        private void txbFixedPhone_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = !char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back;
        }

        private void txbFaxuctInf_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = !char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back;
        }

        private void txbMobileuctInf_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = !char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back;
        }

        public void savedata()
        {
            try
            {
                if (conn.State == ConnectionState.Closed) conn.Open();
                sql = "sp_InsertInformation";
                cmd = new SqlCommand(sql, conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@addresses", txbAddresses.Texts.ToString());
                cmd.Parameters.AddWithValue("@fixedphone", txbFixedPhone.Texts.ToString());
                cmd.Parameters.AddWithValue("@fax", txbFaxuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@mobilephone", txbMobileuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@email", txbEmailuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@website", txbWebuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@category", cmbCategoryuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@industrisector", cmbIndustryuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@turnover", nudTurnoveructInf.Text.ToString());
                cmd.Parameters.AddWithValue("@employee", nudEmployeesuctInf.Text.ToString());
                cmd.Parameters.AddWithValue("@source", cmbSourceuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@deptdiv", cmbDeptuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@regcode", txbRegCode.Texts.ToString());
                cmd.Parameters.AddWithValue("@taxn", txbTaxN.Texts.ToString());
                cmd.Parameters.AddWithValue("@paymentdelay", nudPaymentuctInf.Text.ToString());
                cmd.Parameters.AddWithValue("@lang", txbLanguageuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@accowner", txbAccOwner.Texts.ToString());
                cmd.Parameters.AddWithValue("@team", txbTeamuctInf.Texts.ToString());
                cmd.Parameters.AddWithValue("@companyassoci", cmbCompaniesAssoci.Texts.ToString());
                cmd.Parameters.AddWithValue("@note", rtbNotes.Text.ToString());

                cmd.ExecuteNonQuery();
                conn.Close();
                MessageBox.Show("Insert data successfully", "Information");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Information");
                conn.Close();
                return;
            }
        }
    }
}

现象截图

数据库空值结果

数据库空值结果

Visual Studio设计界面

窗体设计界面

原因分析

核心问题是窗体代码中手动new了一个新的uctInformation实例,但这个实例和设计界面中拖入的UserControl不是同一个对象。用户输入的内容都在设计界面生成的实例里,而你调用的是自己new的空实例的savedata方法,自然会向数据库存入空值。

解决方案

场景1:设计界面拖入UserControl

直接使用设计界面自动生成的UserControl实例(注意设计时给UserControl设置的Name属性,比如默认是uctInformation1),删除手动new的代码:

namespace REMAS.Forms.Account
{
    public partial class frmCreateFixedAssetCategories : Form
    {
        SqlConnection conn = new SqlConnection("Server=localhost;Database=TESTCRUD;User Id=sa;Password=123456");
        SqlCommand cmd;
        SqlDataAdapter adapter;
        SqlDataReader reader;
        DataTable dt;
        string sql, sAction;
        int iID;

        public frmCreateFixedAssetCategories()
        {
            InitializeComponent();
            // 移除手动new实例的代码
        }

        private void btnSaveActions_Click(object sender, EventArgs e)
        {
            // 调用设计界面中UserControl实例的savedata方法
            uctInformation1.savedata();
        }
    }
}

场景2:动态添加UserControl到容器

如果是动态创建并添加UserControl到容器(比如Panel),需要保存添加到容器的那个实例的引用,而不是重新new:

namespace REMAS.Forms.Account
{
    public partial class frmCreateFixedAssetCategories : Form
    {
        SqlConnection conn = new SqlConnection("Server=localhost;Database=TESTCRUD;User Id=sa;Password=123456");
        SqlCommand cmd;
        SqlDataAdapter adapter;
        SqlDataReader reader;
        DataTable dt;
        string sql, sAction;
        int iID;
        private uctInformation uctInformationInstance;

        public frmCreateFixedAssetCategories()
        {
            InitializeComponent();
            // 创建实例并添加到容器
            uctInformationInstance = new uctInformation();
            panel1.Controls.Add(uctInformationInstance);
            uctInformationInstance.Dock = DockStyle.Fill;
        }

        private void btnSaveActions_Click(object sender, EventArgs e)
        {
            // 调用保存的实例的方法
            uctInformationInstance.savedata();
        }
    }
}

内容的提问来源于stack exchange,提问作者Yud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 18:52:04