就像失眠症患者喝咖啡一样,我还有另一个问题要发布。
在表单的加载事件中,我根据作为参数传递给表单构造函数的类的属性创建和初始化控件。组合框和复选框早期失败(方法“initializeControls()”)进入表单创建,但不是稍后(方法“resetData()”)。我无法理解,因为两者都在事件“SomeForm_Load(sender,e)”期间被调用。我做了像使用错误事件一样基本的事情吗?正如我之前的问题帖子中所述,我是 C# 新手。任何指导表示赞赏。如果我也使用太多反射,请随时告诉我,:D。
伪代码,对于我的问题的要点:
public class SomeForm : Form
{
#region fields
private int _id { get; set; }
private int _id2 { get; set; }
#endregion fields
...
public SomeForm()
{
InitializeComponent();
}
public SomeForm(int id, int id2) : this()
{
_id = id;
_id2 = id2;
}
#region init
private void SomeForm_Load(object sender, EventArgs e)
{
method1(); // fails
method2(); // works
}
private void method1()
{
var ds = new []{1,2};
CheckBox cb = new CheckBox();
cb.DataSource = ds;
cb.SelectedValue = _id; // <== this is the problem. these two
this.Controls.Add(cb); // <== steps should be switched.
}
private void method2()
{
cb.SelectedValue = _id2;
}
...
}
真正的代码:
public class SomeForm : Form
{
...
#region fields
...
private MultiState.Update _child { get; set; }
protected object data { get; set; }
private Type _masterType { get; set; }
private List<PropertyInfo> _mpks = new List<PropertyInfo>();
private User _user { get; set; }
#endregion fields
...
public SomeForm()
{
InitializeComponent();
}
public SomeForm(User user, Type amaster, object aobject, Dictionary<string, object> astate) : this()
{
data = aobject;
_masterType = amaster;
dataState = astate;
_user = user;
}
#region init
private void SomeForm_Load(object sender, EventArgs e)
{
initialize();
}
private void initialize()
{
tsData.Visible = false;
if (data != null)
{
initializeControls(); // FAILS!! without exception
dataId = DataService.GetPrimaryKeyValue(data);
resetData(); // SUCCEEDS
}
}
private void initializeControls()
{
...
ComboBox cb = new ComboBox();
cb.Enabled = fdEnabled; // correctly read from linq datacontext custom attribute
cb.FormattingEnabled = true;
cb.Location = new Point(x, y);
cb.Name = _CP_COMBOBOX + pi.Name;
cb.Size = new Size(_WIDTH_CODE, _HEIGHT_SINGLE);
cb.TabIndex = i;
cb.TabStop = true;
cb.Leave += new EventHandler(this.ctlEdit_Leave);
// set drop-down
cb.DataSource = domain; // correctly populated from service class
cb.ValueMember = "Id";
cb.DisplayMember = "Label";
// set default
if (fdDefault != null)
{
下面的作业失败了!!期望的值计算正确(wth,当未注释时),但它被简单地忽略,没有任何例外。
//object wth = GetDomainKeyAsIdentifierSafe(domain, fdDefault, _user); // correctly parsed
cb.SelectedValue = GetDomainKeyAsIdentifierSafe(domain, fdDefault, _user); // HUGE FAIL!!
}
...
}
#endregion init
...
#region persistence
...
protected string resetData()
{
string rc = "";
if (!isDataNew()) // this form only modal
{
//resetDataState();
#region bind-object-vs-set
foreach (Control control in this.Controls)
{
try
{
if (control.Name.StartsWith(_CP_TEXTBOX))
{
MethodInfo mi = data.GetType().GetMethod(DataService.LINQ_GET + control.Name.Substring(_CP_TEXTBOX.Length));
object value = mi.Invoke(data, null);
control.Text = value == null ? "" : value.ToString();
}
else if (control.Name.StartsWith(_CP_CHECKBOX))
{
#region bind-object-vs-set-cbx
bool ck = false;
string scontrol = control.Name.Substring(_CP_CHECKBOX.Length);
MethodInfo mi = data.GetType().GetMethod(DataService.LINQ_GET + scontrol);
object value = mi.Invoke(data, null);
if (value != null)
{
if (value.GetType() == typeof(bool))
{
ck = (bool)value;
}
else if (value.GetType() == typeof(Nullable<bool>))
{
Nullable<bool> nvalue = (Nullable<bool>)value;
if (nvalue.HasValue)
ck = nvalue.Value;
else
ck = AtsService.GetDefaultBoolean(data.GetType(), scontrol);
}
}
CheckBox cbx = (CheckBox)control;
cbx.Checked = ck;
#endregion bind-object-vs-set-cbx
}
else if (control.Name.StartsWith(_CP_COMBOBOX))
{
MethodInfo mi = data.GetType().GetMethod(DataService.LINQ_GET + control.Name.Substring(_CP_COMBOBOX.Length));
object value = mi.Invoke(data, null);
ComboBox cb = (ComboBox)control;
下面的作业神秘地起作用了!!
cb.SelectedValue = value == null ? FormService.NOSELECTION_ID : value; // but this one works!!
}
}
}
}
}
...
#endregion persistence
}
编辑:在成功和失败点添加更大的标志。