表格加载时c#控制值问题

时间:2011-03-09 10:46:13

标签: c# events forms combobox custom-attribute

像失眠者的咖啡一样,我还有另外一个问题要发布。

在表单的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
}

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

3 个答案:

答案 0 :(得分:1)

虽然你的问题不够明确,但我认为你在“initialzeControls()”中创建一个局部变量,并且你期望它们在某种程度上可以在类级别上使用..

你必须在类级别创建控件..可能是我错了,因为你的错误不明确。你必须清楚地表达你的问题,你期待的是什么,为什么以及你实际得到的......

答案 1 :(得分:1)

link 1 dynamic combobox availability

combobox.datasource在绘制之前不可用 - 也就是说,在“this.Controls.Add(cb);”之后

感谢可靠的​​快速反馈,这促使我找到了解决方案。

答案 2 :(得分:0)

由于您使用了模糊的名称并且没有正确记录您的代码,因此有点难以理解您的代码。

我建议您通过设置断点并加入代码来缩小搜索范围:F11