【问题标题】:Change text of a TextBox clicking a Button with Controls created at run-time单击带有在运行时创建的控件的按钮更改文本框的文本
【发布时间】:2019-05-29 13:29:58
【问题描述】:

我试图在单击按钮时更改 TextBox 的文本:两个控件都是在运行时动态创建的。

每次单击另一个按钮时都会创建按钮和文本框。
每个控件的Name 属性由用户使用文本框指定。

例如用户输入“Test1”,则Button命名为btn_Test1,TextBox命名为txt_Test1

按钮应该打开一个FolderBrowserDialog,并且在做出选择之后,文本框会显示选择的路径。

我正在使用以下代码:

protected void button_Click(object sender, EventArgs e)
{
    Button button = sender as Button;
    folderBrowserDialog.ShowDialog();
    string TextName = button.Name.Replace("btn_", "txt_");
    TextBox selectText = new TextBox();
    selectText = this.Controls[TextName] as TextBox;
    selectText.Text = folderBrowserDialog.SelectedPath;
}

但是这部分给了我null:

selectText = this.Controls[TextName] as TextBox;

我在创建控件时确实检查了调试器,因此 TextName 设置了正确的名称。

Buttons 和 TextBoxes 被插入到 TabControls 中,Tab Name 设置为用户输入的值,因此主 TabControl 有 2 个控件。

我正在使用一个名为“TabFolders”的隐藏 TabControl,它将作为创建选项卡克隆的主要参考

我正在使用此代码:

private void CreateDynamicPathButtons(string TabName)
{
    TabPage MyNewTab = new TabPage(TabName);
    TabPage TabCopy1;
    tabControlEmpresas.TabPages.Add(MyNewTab);
    TabControl tc = new TabControl();

    tc.Location = new System.Drawing.Point(6, 6);
    tc.Size = TabFolders.Size;

    for (int i = 0; i < TabFolders.TabCount; i++) {
        TabFolders.SelectTab(i);
        TabCopy1 = new TabPage(TabFolders.SelectedTab.Text);
        foreach (Control c in TabFolders.SelectedTab.Controls) {
            Control cNew = (Control)Activator.CreateInstance(c.GetType());
            cNew.Text = c.Text;
            cNew.Size = c.Size;
            cNew.Location = new System.Drawing.Point(c.Location.X, c.Location.Y);
            cNew.Visible = true;
            if (cNew is TextBox) {
                cNew.Name = "txt_" + MyNewTab.Text + "_" + TabFolders.SelectedTab.Text;
            }
            if (cNew is Button) {
                cNew.Name = "btn_" + MyNewTab.Text + "_" + TabFolders.SelectedTab.Text;
                cNew.Click += new EventHandler(button_Click);
            }
            TabCopy1.Controls.Add(cNew);
        }
        tc.TabPages.Add(TabCopy1);
    }
    MyNewTab.Controls.Add(tc);
}

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    经过多次尝试,我确实找到了一个非常简单的解决方案。

    TextBox selectText = new TextBox();
                selectText = button.Parent.Controls[TextName] as TextBox;
    

    按钮父级拥有所有控件。

    【讨论】:

      【解决方案2】:

      假设button 是您提到的在运行时创建的 Button 控件,您正在创建一个 TextBox 控件,但您没有将它添加到 Form.Controls 集合 (this.Controls.Add([Control]))。

      此外,您应该使用适合您当前布局的逻辑分配一个位置来定位新创建的控件。否则,所有新控件将一个在另一个之上。在示例中,新控件位置是使用字段 (int ControlsAdded) 确定的,该字段跟踪运行时创建的控件数量并添加一些基本布局逻辑。

      但是,如果您想保留这些新控件的引用,您应该将它们添加到 List&lt;Control&gt; 或其他允许在需要时选择它们的集合。

      int ControlsAdded = 0; 
      
      protected void button_Click(object sender, EventArgs e)
      {
          TextBox selectedText = new TextBox();
          selectedText.Size = new Size(300, this.Font.Height);
          selectedText.Location = new Point(100, ControlsAdded * selectedText.Height + 30);
          ControlsAdded += 1;
          this.Controls.Add(selectedText);
          selectedText.BringToFront();
      
          using (var fBD = new FolderBrowserDialog())  {
              if (fBD.ShowDialog() == DialogResult.OK)
                  selectedText.Text = fBD.SelectedPath;
          }
      }
      

      【讨论】:

        【解决方案3】:

        使用selectText = this.Controls[TextName] as TextBox;,您正在尝试查找具有替换名称的按钮,在这种情况下不可用,因此它返回空值。这是逻辑错误。

        string TextName = button.Name.Replace("btn_", "txt_"); 也不会替换按钮名称,它只是将替换的字符串分配给 TextName。

        正确的实现应该是

        protected void button_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;
            folderBrowserDialog.ShowDialog();
            button.Name = button.Name.Replace("btn_", "txt_");
            TextBox selectText = new TextBox();
            selectText = this.Controls[button.Name] as TextBox;
            selectText.Text = folderBrowserDialog.SelectedPath;
        }
        

        【讨论】:

        • string TextName = button.Name.Replace("btn_", "txt_");在这里,我试图获取按钮的名称并将其分配给字符串,然后在 selectText = this.Controls[TextName] as TextBox; 中查找该字符串。我不想更改原始按钮的名称,但由于我分配的名称几乎相同,如果它是一个按钮,它以“btn_”和“txt_”开头的文本
        • 您是否调试并检查您要查找的内容是否在 this.Controls 中可用?
        • 我确实更改了替换代码字符串 TextName = button.Name; TextName = TextName.Replace("btn_", "txt_");调试器只显示一个可用的控件,即使我动态添加了 4 个,所以它不存在
        • 如果不存在,则不存在。您无法添加它。
        • 但我可以在屏幕上看到它们,有 2 个文本框和 2 个按钮,所以我的代码确实添加了它们
        猜你喜欢
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2013-08-23
        • 2018-08-08
        • 1970-01-01
        • 2019-07-08
        • 2022-01-08
        • 1970-01-01
        相关资源
        最近更新 更多