在表单的load事件中,我根据作为参数传递给表单构造函数的类的属性创建和初始化控件。组合框和复选框提前失败(方法“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)
{
失败后的分配!!所需的值可以正确计算(当取消注释时),但只是被忽略而没有任何异常。
//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
}
编辑:在成功和失败点添加更大的标记。
答案 0 :(得分:1)
虽然你的问题不够明确,但我认为你在“initialzeControls()”中创建一个局部变量,并且你期望它们在某种程度上可以在类级别上使用..
你必须在类级别创建控件..可能是我错了,因为你的错误不明确。你必须清楚地表达你的问题,你期待的是什么,为什么以及你实际得到的......
答案 1 :(得分:1)
link 1 dynamic combobox availability
combobox.datasource在绘制之前不可用 - 也就是说,在“this.Controls.Add(cb);”之后
感谢可靠的快速反馈,这促使我找到了解决方案。
答案 2 :(得分:0)
由于您使用了模糊的名称并且没有正确记录您的代码,因此有点难以理解您的代码。
我建议您通过设置断点并加入代码来缩小搜索范围:F11
。