动态生成的文本框
本文关键字:文本 动态 | 更新日期: 2023-09-27 18:26:20
我需要一种动态创建大量文本框并访问其值的方法。
在我的表单中,用户输入一个介于1和50之间的数字,然后必须使用动态名称创建该数量的文本框,即ingredient1、ingredient2、ingredient 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
(其中i是增量)这样就可以使名称为"input1"、"input2"、"input3"等等
与将包含文本框中数据的字符串相同。
我想我会编辑它,因为我似乎误解了这个问题
您可以将其绑定为以下形式:
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));
}
}
}
与其创建一个字符串来保存文本框中的值,不如将文本框保留在一个列表中,并在需要时从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);
}
编辑:如果每个成分都有多个值,那么使用用户控件,以最方便的方式显示您想要的属性-汇总数量、重量、描述(例如"一小撮"盐)-让代码访问这些属性。