不眠症のコーヒーのように、私は投稿する別の質問があります。
フォームのロードイベントでは、引数としてフォームのコンストラクターに渡されたクラスの属性に基づいてコントロールを作成および初期化します。コンボボックスとチェックボックスは、フォームの作成に早い段階で失敗し(メソッド "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
}
編集:成功点と失敗点でより大きなフラグを追加しました。