winforms 来自用户输入窗体的C#传递值

qvk1mo1f  于 2023-03-03  发布在  C#
关注(0)|答案(2)|浏览(146)

我是System.Windows.Forms的新手,所以请原谅我的新手问题。我创建了一个简单的用户输入表单,它有两个文本框和一个按钮。目的是用户在tbox_H和tbox_V中键入一个值,并且那些值被传递回初始化表单的代码。两个文本框的默认值都是“1”。我已经确认这些值会随着用户在TextChanged事件中的输入而改变,并且这些值在MouseClick事件中仍然存在。但是,只传递了默认值。

namespace MyCommands
{
    partial class MyForm
    {
        //Windows Form Designer generated code
        //some other generated code omitted for brevity
        private System.Windows.Forms.Button button1;
        public System.Windows.Forms.TextBox tbox_H;
        public System.Windows.Forms.TextBox tbox_V;

        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.tbox_H = new System.Windows.Forms.TextBox();
            this.tbox_V = new System.Windows.Forms.TextBox();
            // button1
            this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.button1.Name = "button1";
            this.button1.Text = "OK";
            this.button1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.button1_MouseClick);
            // tbox_H
            this.tbox_H.Name = "tbox_H";
            this.tbox_H.Text = "1";       //default value
            this.tbox_H.TextChanged += new System.EventHandler(this.tbox_H_TextChanged);
            // tbox_V
            this.tbox_V.Name = "tbox_V";
            this.tbox_V.Text = "1"; //default value
            this.tbox_V.TextChanged += new System.EventHandler(this.tbox_V_TextChanged);
            // Form
            this.AcceptButton = this.button1;
            this.Controls.Add(this.button1);
            this.Controls.Add(tbox_H);
            this.Controls.Add(tbox_V);
        }
    }
}

using System.Windows.Forms;

namespace MyCommands
{
    public partial class MyForm : Form
    {
        public MyForm()
        {
        InitializeComponent();
        }

        private void tbox_H_TextChanged(object sender, EventArgs e)
        {
            MessageBox.Show("At TextBox", tbox_H.Text);   //Confirmed value changes
        }

        private void tbox_V_TextChanged(object sender, EventArgs e)
        {
            MessageBox.Show("At TextBox", tbox_V.Text);  //Confirmed value changes
        }

        private void button1_MouseClick(object sender, MouseEventArgs e)
        {
            MessageBox.Show("At MouseClick", tbox_H.Text + ", " + tbox_V.Text); //Values confirmed
            this.Close();
        }
    }
}

namespace MyCommands
{
    public class MyCommand1
    {
        MyForm form1 = new MyForm();
        form1.ShowDialog();
       int var1 = Convert.ToInt32(form1.tbox_H.Text); //only default value passed
       int var2 = Convert.ToInt32(form1.tbox_H.Text); //only default value passed
    }
}

我怀疑将文本框声明为Public可能不是最佳方法。从用户输入表单传递值的最佳实践是什么?非常感谢您的指导。

zzlelutf

zzlelutf1#

我运行了你的代码,一切正常:

private void InitializeComponent()
    {
        this.SuspendLayout();
        // 
        // Form2
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(800, 450);
        this.Name = "Form2";
        this.Text = "Form2";
        this.ResumeLayout(false);

        this.button1 = new System.Windows.Forms.Button();
        this.tbox_H = new System.Windows.Forms.TextBox();
        this.tbox_V = new System.Windows.Forms.TextBox();
        // button1
        this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
        this.button1.Name = "button1";
        this.button1.Text = "OK";
        button1.Location = new Point(100, 100);//Missing in your code
        this.button1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.button1_MouseClick);
        // tbox_H
        this.tbox_H.Name = "tbox_H";
        this.tbox_H.Text = "1";       //default value
        this.tbox_H.TextChanged += new System.EventHandler(this.tbox_H_TextChanged);
        // tbox_V
        this.tbox_V.Name = "tbox_V";
        this.tbox_V.Text = "1"; //default value
        tbox_V.Location = new Point(50, 50);//Missing in your code
        this.tbox_V.TextChanged += new System.EventHandler(this.tbox_V_TextChanged);
        // Form
        this.AcceptButton = this.button1;
        this.Controls.Add(tbox_H);//Missing in your code
        this.Controls.Add(tbox_V);//Missing in your code
        this.Controls.Add(this.button1);
    }

我只是注解了你代码中缺失的部分。没有减速的问题。
关于最佳实践,你可以学习在WPF(下一代Windows窗体)here上使用的MVVM模式。如果很难学习MVVM,你也可以在那里创建用户控件并封装窗体逻辑。
Windows窗体和他的姐夫WebForm都遭受了维护问题的困扰。

vql8enpb

vql8enpb2#

你的直觉很准:
我怀疑将文本框声明为Public可能不是最好的方法。
更正确的做法是保留UI元素private,并在确保输入有效后将每个必要的值公开为public property

    • 属性**

用户输入表单的目标:

  • 提供两个整数值V和H
  • 确保公共信息始终有效(即使内部UI状态无效)。
  • 订阅文本更改事件和可见更改事件。这可以在"设计器"视图或窗体构造函数中完成,如下所示。*
public partial class UserInputForm : Form
{
    public UserInputForm()
    {
        InitializeComponent();
        textBoxV.TextChanged += onAnyTextChanged;
        textBoxH.TextChanged += onAnyTextChanged;
        VisibleChanged += onVisibleChanged;
    }

    // The public properties are available whether
    // the form is currently visible or not.
    public int V { get; private set; } = 1;
    public int H { get; private set; } = 1;

    // Whenever the form is shown, refresh the text boxes
    // with the last VALID values for V and H
    private void onVisibleChanged(object sender, EventArgs e)
    {
        if (Visible)
        {
            textBoxV.Text = V.ToString();
            textBoxH.Text = H.ToString();
        }
    }
    .
    .
    .
}
    • 文本更改**

在更改UI时验证表单。例如,此简单方案会在任何文本框中的文本发生更改时同时查看两个文本框。如果存在无效文本输入,则OK按钮将被禁用。

private void onAnyTextChanged(object sender, EventArgs e)
{
    int value;
    bool isValid = true;
    if(int.TryParse(textBoxV.Text, out value))
    {
        V = value;
        textBoxV.BackColor= Color.White;
    }
    else
    {
        isValid = false;
        textBoxV.BackColor = Color.LightSalmon;
    }
    if (int.TryParse(textBoxH.Text, out value))
    {
        H = value;
        textBoxV.BackColor = Color.White;
    }
    else
    {
        isValid = false;
        textBoxV.BackColor = Color.LightSalmon;
    }
    // Enable or disable the OK button based on
    // valid integer values of both textboxes.
    buttonOk.Enabled = isValid;
}
    • 主窗体**

您可能希望用户输入窗体在每次显示时都"记住"它以前的值。因此,主窗体会将对话框声明为成员变量,并且在首先确保输入操作没有被取消之后,能够检索_userInputForm.V_userInputForm.H的整数值。

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();

    UserInputForm _userInputForm= new UserInputForm();
    private void buttonShowUserInput_Click(object sender, EventArgs e)
    {
        // Make sure the dialog hasn't been cancelled by [X]
        if(DialogResult.OK.Equals(_userInputForm.ShowDialog()))
        {
            richTextBox.Clear();
            richTextBox.SelectionColor= Color.Navy;
            richTextBox.AppendText($"V={_userInputForm.V}{Environment.NewLine}");
            richTextBox.SelectionColor = Color.DarkGreen;
            richTextBox.AppendText($"H={_userInputForm.H}{Environment.NewLine}");
        }
        else
        {
            richTextBox.Clear();
            richTextBox.SelectionColor = Color.Red;
            richTextBox.AppendText($"CANCELLED{Environment.NewLine}");
        }
    }
}

相关问题