3

解决方案

我现在对此很自责,但您会在下面的代码中注意到,我正在为 Form4 使用参数化构造函数。C# 中参数化构造函数的标准过程是:this()在声明之后使用(我认为,至少对于 Forms)。这首先调用未参数化/默认构造函数,其中包含InitializeComponent()设置表单及其控件。

InitializeComponent()如果您使用过,绝对应该在参数化构造函数中:this(),因为它会使用“新”控件重新初始化您的表单。这会导致您的表单和控件处于模棱两可的状态,以及我得到的奇怪行为。

原始问题

我有一个表单,我希望控件(包括文本框)在第一个视图中具有初始值。这些值来自表单构建期间的一条 SQL 语句,因此我无法使用表单设计器。此表单的元素/控件也是从几乎相同的表单复制粘贴的,因为该表单是“添加”,而该表单是“编辑”

问题是这样的:使用调试器显示我成功地从 SQL 中获取了良好的数据,并且设置textbox.Text成功,但是当显示表单时,它并没有反映所做的更改。这里的答案:https ://stackoverflow.com/a/7830769/1655707暗示可以简单地设置该值(大概在初始化或加载期间)。

我已经尝试在初始化期间、Load 事件和 Shown 事件中这样做,但这些都不起作用。打电话Refresh()Application.DoEvents()无所作为。有什么我想念的吗?某些阻止此文本框正确更新/显示的事件?复制粘贴控件是否有意外的副作用?

我尝试并以这种方式设置的所有控件都不会显示更改后的值,但文本框是最简单的,因为它没有索引可以弄乱。

    public Form4(int collIDFromParent, string collNameFromParent): this()
    {
        InitializeComponent();

        retCollID = collIDFromParent;
        retCollName = collNameFromParent;

        //Initialize these here so they activate on first use0
        button1.DialogResult = DialogResult.None;
        button2.DialogResult = DialogResult.Cancel;

        //PopulateEditData goes first for potential SQL failure
        PopulateEditData();

        textBox6.Text = "TEST";
    }

    private void Form4_Load_1(object sender, EventArgs e)
    {
        textBox1.Text = "TEST";
    }

    private void Form4_Shown_1(object sender, EventArgs e)
    {
        textBox2.Text = "TEST";
    }

是的,他们设置了不同的文本框,但它们都不起作用,所以差别不大。

一个典型的文本框更改处理程序。有人可能会认为它当前的编写方式可能会引发某种重置,但注释掉一行并不会改变我担心的行为。

    private void textBox6_TextChanged_2(object sender, EventArgs e)
    {
            retCollName = textBox6.Text;
    }
4

3 回答 3

1

通过功能之间的简单更改(例如添加与编辑),表单的核心功能不会改变。您尝试处理的两个函数之间的唯一核心区别是一个新对象和一个现有对象。正因为如此,一个表单会比两个单独的表单要好得多。也省了很多工作,是OOP的核心之一。

我建议的另一件事是在创建表单之前检索数据。创建一个数据对象,其中包含您从数据库中检索的所有属性。为该数据类提供一个 Load 方法,该方法接受您要查找的记录的任何标识符。现在您已准备好迎接更轻松的时光。

为了示例,我将在这里制作一些默认按钮,您的体验可能会有所不同。:)

AddButton_Click(//default button click parameters) {
    Widget widget = new Widget();
    OpenWidgetForm(widget);
}

EditButton_Click(//default button click parameters) {
    Widget widget = new Widget();
    // You'll use the way you have now to determine which record to load,
    // and turn it to the id variable
    widget.Load(id);
    OpenWidgetForm(widget);
}

OpenWidgetForm(Widget widget) {
    frmWidget frm = new frmWidget(widget);
    frm.Show();
}

该代码将采用任何可以将您带到“添加/编辑”表单的形式。

现在在您的添加/编辑表单中,您将像这样更改它:

private Widget _widget;

public frmWidget() {
    Widget widget = new Widget();
    _widget = widget;
    LoadWidget();
}

public frmWidget(Widget widget) {
    _widget = widget;
    LoadWidget();
}

public void LoadWidget() {
    // go through each of the properties of your object
    // and set the values to the Text properties of each Textbox.
    txtName.Text = _widget.Name;
}

有了这个,你应该很高兴。如果您有任何问题,请告诉我。

于 2013-01-18T21:09:56.483 回答
0

我做了一个快速项目来测试这个功能。所有这三个选项都成功设置了 TextBox 的值。您在此处遇到的问题未在发布的代码中显示。之后有什么东西改变了 TextBox 的值,或者你引用了错误的 TextBoxes。我刚刚完成了与我们的应用程序类似的问题的调试。事实证明,我们不知何故有两组重叠的文本框(我们实际使用的文本框位于一组空文本框的下方)。

    public Form1()
    {
        InitializeComponent();

        textBox1.Text = "TEST";
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        textBox2.Text = "TEST";
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        textBox3.Text = "TEST";
    }
于 2013-01-18T20:12:43.890 回答
0

这可能是一个比这个问题所需的更简单的答案,但请确保您实际上正在调用Controls.Add(textBox1). 我注意到到目前为止没有人提到这一点。首先签入 Designer 生成的代码。

如果您要动态添加控件,则必须自己调用它。

于 2013-01-18T20:14:55.850 回答