【问题标题】:String array property returns text property of textboxes on form字符串数组属性返回表单上文本框的文本属性
【发布时间】:2012-05-17 17:45:48
【问题描述】:

所以我有一个由脚本动态生成的表单,为每个作为参数提取的字符串都有一个标签和一个文本框。我希望用户填写每个文本框,然后选择 OK 按钮。之后我想处理每个文本框的每个项目。之前只有一项的时候,我写了一个很简单的属性来获取文本框的值。

Public string Text { get { return textbox1.Text; } }

我希望我可以用动态数量的文本框做同样优雅的事情。

Public string [] Text { get { return **Each text box text as an array**; } }

我已经考虑了一段时间,但我想不出一种优雅的方式来设置它,这是文本框添加到表单的方式...

string[] keywords = Environment.GetCommandLineArgs();
int placement = 10;
foreach (string keyword in keywords)
{
    if (keyword == keywords[0])
        continue;
    Label lbl = new Label();
    lbl.Text = keyword;
    lbl.Top = placement;
    this.Controls.Add(lbl);
    TextBox txt = new TextBox();
    txt.Top = placement;
    txt.Left = 100;
    this.Controls.Add(txt);

    placement += 20;
}

我可以在表单关闭时遍历每个文本框的文本并用值填充公共数组,但我宁愿想出一些更优雅的东西,并摆脱强迫做事的习惯。有人对如何做到这一点有任何很酷的想法吗?我想我可以将所有文本框添加到一个数组中,然后让字符串属性以某种方式获取指定文本框的文本,或者只是将文本框数组设为公共属性。有没有办法写出这样的东西...

Public string [] Text { get { return TextBoxArray[**value trying to be gotten**].Text; } }

或者这对于一个属性来说太过分了,需要一个方法来代替?任何人有任何其他想法?我意识到这是一个微不足道的问题,可以通过多种方式解决,我只是希望通过一些很酷的方式来拓宽我的视野来完成这样的事情。

【问题讨论】:

    标签: c# arrays winforms


    【解决方案1】:

    其他选项可能更好,但这可能是最直接和简洁的:(使用 LINQ,添加 using System.Linq;,需要 .NET 3.5 或更高版本)

    public string[] Text { get { return Controls.OfType<TextBox>().Select(x => x.Text).ToArray(); } }
    

    这和AlejoBrz的方案很相似,但是使用LINQ更加清晰简洁。

    【讨论】:

    • 我最喜欢这个答案,非常简洁,并且用 1 行完全符合我的要求。谢谢!
    • @KDiTraglia 我也最喜欢它!
    • 啊,我假设你有一个参数名称/值的事情,但看起来情况并非如此 :)
    【解决方案2】:

    这是一个想法:

    Public System.Collections.Generic.List<string> Text { 
        get {
            System.Collections.Generic.List<string> returnValue = new string[textBoxCount];
            foreach (Control ctrl in this.Controls)
                if (ctrl.GetType() == typeof(TextBox))
                    returnValue.Add(((TextBox)ctrl).Text);
            return returnValue;
       }
    }
    

    当然,它会遍历您的所有控件,但至少您不必将它们保存在内存中的某种变量中,例如 System.Collections.Generic.List。或者你可以这样做并在这个 foreach 上删除 if。

    【讨论】:

      【解决方案3】:

      从技术上讲,属性只是 getter/setter 方法的语法糖 - 所以属性可以做任何方法可以做的事情(但大多数时候它不应该!)

      假设您的命令行参数不能重复,我只需将所有文本框添加到 Dictionary 对象。

      基本上在启动时:

      创建一个:

      Dictionary<string, TextBox> boxes;
      

      使用命令参数作为键在启动代码中添加文本框

      boxes.Add(commandName, newTextBox);
      

      然后在您的 getter 中,您可以使用

      访问字典
      boxes[commandName]
      

      这将返回您可以操作的文本框。当然,这都是强类型的:)

      下面是一些示例代码:

      string[] keywords = Environment.GetCommandLineArgs(); 
      Dictionary<string, TextBox> boxes = new Dictionary<string, TextBox>();
      int placement = 10; 
      
      foreach (string keyword in keywords) 
      { 
          if (keyword == keywords[0]) 
              continue; 
          Label lbl = new Label(); 
          lbl.Text = keyword; 
          lbl.Top = placement; 
          this.Controls.Add(lbl); 
          TextBox txt = new TextBox(); 
          txt.Top = placement; 
          txt.Left = 100; 
          this.Controls.Add(txt); 
          placement += 20; 
          boxes.Add(keyword, txt);
      } 
      

      那么我想你不需要 getter - 只需让 box 字典可见

      public Dictionary<string, TextBox> Boxes { get { return boxes; } }
      

      如果您对文本框不感兴趣而只想要值:

      public Dictionary<string, string> Arguments 
      {
        get 
        {
           Dictionary<string, string> vals = new Dictionary<string, string>();
      
           foreach(KeyValuePair<string, TextBox> kvp in boxes) 
           {
             vals.Add(kvp.Key, kvp.Value.Text);
           }
      
           return vals;
         }
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-16
      • 2010-11-27
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 2013-05-18
      相关资源
      最近更新 更多