3

Solution

I am now kicking myself over this, but you'll notice in the code below, that I am using a parameterized constructor for Form4. Standard procedure for a parameterized constructor in C# is to use :this() after the declaration (I think, at least for Forms). This calls the unparameterized/default constructor first, which contains InitializeComponent(), which sets up the form and its controls.

InitializeComponent() should most definitely not be in the parameterized constructor if you have used :this(), since it re-initializes your form with 'new' controls. This leads to an ambiguous state for your Form and controls, and the weird behavior I was getting.

Original Question

I have a form in which I would like the controls (including a textbox) to have initial values on first view. The values come from an SQL statement during the Form's construction, so I can't use the Form designer. This form's elements/controls were also copy-pasted from a nearly-identical form since that one is 'Add', and this one is 'Edit'

Problem is this: Using the debugger shows that I successfully get good data from the SQL, and that setting the textbox.Text succeeds, but when the form is displayed, it does not reflect the changes made. The answer here: https://stackoverflow.com/a/7830769/1655707 implies that the value can simply be set (presumably during initialization or load).

I've tried doing it during initialization, in the Load event, and the Shown event, and none of those work. Calling Refresh() and Application.DoEvents() also did nothing. Is there something I am missing? Some event that prevents this textbox from updating/displaying properly? Did copy-pasting the controls have unintended side-effects?

None of the controls I try and set this way display the changed value, but textbox was the simplest since it does not have indices to mess with.

    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";
    }

And yes, they are setting different text boxes, but none of them work, so it makes little difference.

A typical textBox change handler. One might think that the way it's currently written might invoke some sort of resetting, but commenting out that one line does not change the behavior I'm concerned about.

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

3 に答える 3

1

機能間の単純な変更 (追加と編集など) では、フォームのコア機能は変更されません。処理しようとしている 2 つの関数の唯一の主な違いは、新しいオブジェクトと既存のオブジェクトです。そのため、2 つの別々のフォームよりも 1 つのフォームの方がはるかに優れています。また、多くの作業を節約し、OOP のコアの 1 つです。

もう 1 つお勧めすることは、フォームを作成する前にデータを取得することです。データベースから取得するすべてのプロパティを保持するデータ オブジェクトを作成します。そのデータ クラスに、探しているレコードの識別子を受け取る 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

この機能をテストする簡単なプロジェクトを作成しました。これら 3 つの選択肢はすべて、TextBox の値を正常に設定します。投稿されたコードでは表示されない問題がここにあります。後で何かが TextBox の値を変更しているか、間違った TextBox を参照しています。私たちのアプリケーションで同様の問題のデバッグが完了しました。どういうわけか、重複する 2 つの TextBox のセットがあることがわかりました (実際に使用していたものは、空の TextBox のセットの下にありました)。

    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)。これまで誰もこれについて言及していないことに気付きました。まず、デザイナーが生成したコードをチェックインします。

コントロールを動的に追加する場合は、自分で呼び出す必要があります。

于 2013-01-18T20:14:55.850 に答える