0

就像失眠症患者喝咖啡一样,我还有另一个问题要发布。

在表单的加载事件中,我根据作为参数传递给表单构造函数的类的属性创建和初始化控件。组合框和复选框早期失败(方法“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
}

编辑:在成功和失败点添加更大的标志。

4

2 回答 2

1

尽管您的问题还不够清楚,但我认为您正在“initialzeControls()”中创建一个局部变量,并且您希望它们以某种方式在类级别可用..

您必须为此在班级级别创建控件..可能是我错了,因为您的错误不清楚。你必须清楚地提出你的问题,你期望什么,为什么以及你实际得到什么..

于 2011-03-09T11:13:56.500 回答
0

由于您使用了模棱两可的名称并且没有正确记录您的代码,因此很难遵循您的代码墙。

我建议您通过设置断点并单步执行代码来缩小问题范围:F11.

于 2011-03-09T11:30:52.427 回答