我需要一种动态创建多个文本框并访问其值的方法。
在我的表单中,用户输入1到50之间的数字,然后必须使用动态名称创建该数量的文本框,即成分1,成分2,成分3,...成分50等。
我有一个for循环,会使用该值创建多个文本框,但是如何将文本框值存储在字符串变量中?
这是for循环当前为空
int i = Form1.ingredientCount;
for (i = 1; i < Form1.ingredientCount; i++)
{
//create new text box
//create new string that then holds value from text box
}
澄清:
用户在上一页输入一个号码。
然后,此数字确定创建的文本框数和创建的字符串数。
文本框和字符串需要在for循环中具有唯一生成的ID。
我还需要另一个文本框来说明每种成分的重量,尽管我可以自己解决这个问题。
所以基本上我希望每个文本框和字符串都被命名为
"input" + i
(我增加的地方)
这样就可以使名称为“input1”,“input2”,“input3”等等。
与包含文本框数据的字符串相同。
答案 0 :(得分:0)
我以为我会编辑它,因为我似乎误解了这个问题
你可以在表格中将其绑定如下:
public partial class Form1 : Form
{
Recepie pancakes = new Recepie();
IList<UniqueHolder> items = new List<UniqueHolder>();
public Form1()
{
InitializeComponent();
pancakes.Ingredients.Add(new Ingredient { Title = "Milk - 250 gr" });
pancakes.Ingredients.Add(new Ingredient { Title = "Butter - 25 gr" });
pancakes.Ingredients.Add(new Ingredient { Title = "Oil - 1 large spoon" });
pancakes.Ingredients.Add(new Ingredient { Title = "Sugar - 100 gr" });
pancakes.Ingredients.Add(new Ingredient { Title = "Flower - 200 gr" });
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
for (var i = 0; i < pancakes.Ingredients.Count; i++)
{
Ingredient ing = pancakes.Ingredients[i];
TextBox tb = new TextBox { Location = new Point(10, i * 30), Size = new Size(200, 20), Text = ing.Title };
UniqueHolder uh = new UniqueHolder { Ingredient = ing, TextBox = tb };
this.Controls.Add(tb);
}
}
}
独特的持有者对成分或文本框中的更改进行数据绑定
public class UniqueHolder : IDisposable
{
public Guid UniqueID { get; set; }
public override bool Equals(object obj)
{
if (obj is UniqueHolder)
{
return Guid.Equals(((UniqueHolder)obj).UniqueID, this.UniqueID);
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return UniqueID.GetHashCode();
}
private TextBox textbox;
public TextBox TextBox
{
get
{
return textbox;
}
set
{
if (object.Equals(textbox, value))
{
return;
}
if (textbox != null)
{
textbox.TextChanged -= OnTextChanged;
}
textbox = value;
if (textbox != null)
{
textbox.TextChanged += OnTextChanged;
}
}
}
private Ingredient ingredient;
public Ingredient Ingredient
{
get
{
return ingredient;
}
set
{
if (object.Equals(ingredient, value))
{
return;
}
if (ingredient != null)
{
ingredient.PropertyChanged -= OnIngredientChanged;
}
ingredient = value;
if (ingredient != null)
{
ingredient.PropertyChanged += OnIngredientChanged;
}
}
}
public UniqueHolder()
{
this.UniqueID = Guid.NewGuid();
}
protected virtual void OnIngredientChanged(object sender, PropertyChangedEventArgs e)
{
if (string.Equals(e.PropertyName, "Title", StringComparison.OrdinalIgnoreCase))
{
if (TextBox == null)
{
return;
}
TextBox.Text = Ingredient.Title;
}
}
protected virtual void OnTextChanged(object sender, EventArgs e)
{
var tb = sender as TextBox;
if (tb == null)
{
return;
}
if (Ingredient == null)
{
return;
}
Ingredient.Title = tb.Text;
}
public void Dispose()
{
Ingredient = null;
TextBox = null;
}
}
你可以使用这样的成分回到收件人
public class Recepie : IDisposable
{
private readonly IList<Ingredient> ingredients = new ObservableCollection<Ingredient>();
public IList<Ingredient> Ingredients
{
get
{
return ingredients;
}
}
protected virtual void OnIngredientsListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
var ing = item as Ingredient;
if (ing == null)
{
continue;
}
ing.Recepie = null;
}
}
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
var ing = item as Ingredient;
if (ing == null)
{
continue;
}
ing.Recepie = this;
}
}
}
public Recepie()
{
var obs = Ingredients as INotifyCollectionChanged;
if (obs != null)
{
obs.CollectionChanged += OnIngredientsListChanged;
}
}
public void Dispose()
{
int total = Ingredients.Count;
for (int i = total; --i >= 0; )
{
Ingredients.RemoveAt(i);
}
var obs = Ingredients as INotifyCollectionChanged;
if (obs != null)
{
obs.CollectionChanged -= OnIngredientsListChanged;
}
}
}
public class Ingredient : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Recepie recepie;
public virtual Recepie Recepie
{
get
{
return recepie;
}
set
{
if (object.Equals(recepie, value))
{
return;
}
recepie = value;
RaisePropertyChanged("Recepie");
}
}
private string title;
public string Title
{
get
{
return title;
}
set
{
if (string.Equals(title, value))
{
return;
}
title = value;
RaisePropertyChanged("Title");
}
}
protected virtual void RaisePropertyChanged(string propertyName)
{
var local = PropertyChanged;
if (local != null)
{
local.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 1 :(得分:0)
不是创建一个字符串来保存文本框中的值,而是将文本框保存在列表中,并在需要时从Text属性中获取值:然后您不需要连接TextChanged事件等。编辑:您不需要字符串变量来存储文本框文本,因为您现在可以通过列表和Text属性在需要时对其进行引用。
// a field
List<TextBox> ingredientTextBoxes = new List<TextBox>();
private void Populate(int ingredientCount)
{
for (i = 1; i < ingredientCount; i++)
{
// Assign a consecutive name so can order by it
TextBox tb = new TextBox { Name = "IngredientTextbox" + i};
ingredientTextBoxes.Add(tb);
}
}
// when you want the ingredients
public List<string> GetIngredients
{
List<string> ingredients = new List<string>();
foreach (var tb in ingredientTextBoxes)
{
ingredients.Add(tb.text);
}
return ingredients;
}
// contains
private List<string> GetIngredientsMatching(string match)
{
// Contains really should take a StringComparison parameter, but it doesn't
return ingredientTextBoxes
.Where(t => t.Text.ToUpper().Contains(match.ToUpper()))
.Select(t => t.Text);
}
编辑:如果你要为每种成分提供多个值,那么使用一个用户控件来公开你想要的属性 - 总结数量,重量,描述(例如“一小撮盐”) - 以最方便的方式访问这些属性的代码。