寻找 C# 中不同类型用户输入的数组列表声明的良好实践
Looking for a Good Practice of Array List Declaration of different types of user inputs in C#
我需要帮助来尝试使用此算法缩短长代码。
我在我的文本框字段中使用它
Textbox[] Fields = new Textbox[] { txtbox1, txtbox2, txtbox3.. };
string[] arr = { stringVariable1, stringVariable2, stringVariable3.. };
int cnt = 0;
foreach(var r in Fields.AsEnumerable())
{
r.Text = arr[cnt].toString();
cnt++;
}
因此,当加载表单时,如果变量为空或有值,将根据变量填充用户输入字段。
但是如果我有不同类型的字段怎么办?例如日期选择器值、组合框和文本框、单选按钮和复选框字段。
object[] fields = new object[] { datepicker1, Txtbox1, ComboBox1, CheckBox1 };
将它与我用不同类型的对象声明的数组匹配
object[] arr = { DateVar1, TxtBoxVarString1, ComboBoxstring1, CboxBool1, int.. }
是否可以声明这样的事情,这样我就可以缩短我的代码,或者我必须手动完成,因为这是不可能的。
我试过这个代码:
ArrayList arrvar = new ArrayList(); object[] obj = new object[] { datevarvalue1, cboxvarbool1, rbtnvarbool1, stringvar1.. etc.. etc.. }
arrvar.addrange(obj); try { List Fields = new List { AddinfoDOB.Value, CheckBox1.Checked, RadioButton1.Checked, AddinfoPlaceOfBirth.Text, AddInfoCmbBoxBloodT.Text, AddInfoCmbBoxOrigin.Text, AddInfoCmbBoxCitizenship.Text, AddInfoCmbBoxLanguage.Text, AddInfoAddress01.Text };
int cnt = 0;
foreach (object r in Fields.AsEnumerable())
{
Fields[cnt] = arrvar[cnt];
cnt++;
}
}
catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
错误信息:"Collection was modified; enumeration operation may not execute."
实际上你可以声明那种数组。我刚刚测试了它并且它有效。以此为例:
添加一个按钮和一个复选框。
using System.Windows.Forms;
string temp = "Hi!";
Object[] arr = new Object[] { button1, checkBox1, temp };
foreach(Object a in arr)
{
if (a is button)
MessageBox.Show(((Button)a).Name);
else if (a is CheckBox)
MessageBox.Show(((CheckBox)a).Name);
else if (a is String)
MessageBox.Show(((String)a));
}
您可以通过引入 "update" 函数集合来做到这一点
创建更新函数集合和对应的值集合
var updateFunctions = new List<Action<object>>
{
value => textbox.Text = (string)value,
value => datepicker.Value = (DateTime)value,
value => checkbox.Checked = (bool)value,
};
var values = new List<object>
{
"TextBox value",
DateTime.Now,
true,
};
for(var index = 0; i < updateFunctions.Count; i++)
{
var update = updateFunctions[i];
var value = values[i];
update(value);
}
但对我来说,这种方法似乎不像 "hack-workaround" 那样出价低,因为您需要检查集合 values
和 control updates
是否都应该在 "sync" 中。
同样可以通过 little bid cleaner 方式的数据绑定来实现
为要在控件中显示的值创建 class
public class DisplayData
{
public string Name {get; set; }
public DateTime Birthdate {get; set; }
public bool IsActive {get; set; }
}
然后在表单构造函数中"bind"控制数据
public YourForm() // Form constructor
{
InitializeComponents();
var data = new DisplayData
{
Name = "name",
Birthdate = DateTime.Now,
IsActive = true
};
textbox.DataBindings.Add("Text", data, "Name");
dateTimePicker.DataBindings.Add("Value", data, "Birthdate");
checkBox.DataBindings.Add("Checked", data, "IsActive");
}
当您更改控件值时,data
实例中对应的值也将更改。
如果您使 DisplayData
class 实现了 INotifyPropertyChanged
接口,并且每次您更改 data
实例中的值时都会引发 PropertyChanged
事件 - 控件将是自动更新。
我需要帮助来尝试使用此算法缩短长代码。
我在我的文本框字段中使用它
Textbox[] Fields = new Textbox[] { txtbox1, txtbox2, txtbox3.. };
string[] arr = { stringVariable1, stringVariable2, stringVariable3.. };
int cnt = 0;
foreach(var r in Fields.AsEnumerable())
{
r.Text = arr[cnt].toString();
cnt++;
}
因此,当加载表单时,如果变量为空或有值,将根据变量填充用户输入字段。
但是如果我有不同类型的字段怎么办?例如日期选择器值、组合框和文本框、单选按钮和复选框字段。
object[] fields = new object[] { datepicker1, Txtbox1, ComboBox1, CheckBox1 };
将它与我用不同类型的对象声明的数组匹配
object[] arr = { DateVar1, TxtBoxVarString1, ComboBoxstring1, CboxBool1, int.. }
是否可以声明这样的事情,这样我就可以缩短我的代码,或者我必须手动完成,因为这是不可能的。
我试过这个代码:
ArrayList arrvar = new ArrayList(); object[] obj = new object[] { datevarvalue1, cboxvarbool1, rbtnvarbool1, stringvar1.. etc.. etc.. }
arrvar.addrange(obj); try { List Fields = new List { AddinfoDOB.Value, CheckBox1.Checked, RadioButton1.Checked, AddinfoPlaceOfBirth.Text, AddInfoCmbBoxBloodT.Text, AddInfoCmbBoxOrigin.Text, AddInfoCmbBoxCitizenship.Text, AddInfoCmbBoxLanguage.Text, AddInfoAddress01.Text };
int cnt = 0;
foreach (object r in Fields.AsEnumerable())
{
Fields[cnt] = arrvar[cnt];
cnt++;
}
}
catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
错误信息:"Collection was modified; enumeration operation may not execute."
实际上你可以声明那种数组。我刚刚测试了它并且它有效。以此为例:
添加一个按钮和一个复选框。
using System.Windows.Forms;
string temp = "Hi!";
Object[] arr = new Object[] { button1, checkBox1, temp };
foreach(Object a in arr)
{
if (a is button)
MessageBox.Show(((Button)a).Name);
else if (a is CheckBox)
MessageBox.Show(((CheckBox)a).Name);
else if (a is String)
MessageBox.Show(((String)a));
}
您可以通过引入 "update" 函数集合来做到这一点
创建更新函数集合和对应的值集合
var updateFunctions = new List<Action<object>>
{
value => textbox.Text = (string)value,
value => datepicker.Value = (DateTime)value,
value => checkbox.Checked = (bool)value,
};
var values = new List<object>
{
"TextBox value",
DateTime.Now,
true,
};
for(var index = 0; i < updateFunctions.Count; i++)
{
var update = updateFunctions[i];
var value = values[i];
update(value);
}
但对我来说,这种方法似乎不像 "hack-workaround" 那样出价低,因为您需要检查集合 values
和 control updates
是否都应该在 "sync" 中。
同样可以通过 little bid cleaner 方式的数据绑定来实现
为要在控件中显示的值创建 class
public class DisplayData
{
public string Name {get; set; }
public DateTime Birthdate {get; set; }
public bool IsActive {get; set; }
}
然后在表单构造函数中"bind"控制数据
public YourForm() // Form constructor
{
InitializeComponents();
var data = new DisplayData
{
Name = "name",
Birthdate = DateTime.Now,
IsActive = true
};
textbox.DataBindings.Add("Text", data, "Name");
dateTimePicker.DataBindings.Add("Value", data, "Birthdate");
checkBox.DataBindings.Add("Checked", data, "IsActive");
}
当您更改控件值时,data
实例中对应的值也将更改。
如果您使 DisplayData
class 实现了 INotifyPropertyChanged
接口,并且每次您更改 data
实例中的值时都会引发 PropertyChanged
事件 - 控件将是自动更新。