• ********C# Winforms TabControl elements reading as empty until TabPage selected


    C# Winforms TabControl elements reading as empty until TabPage selected
     
     
    I have Winform app I am writing in C#. On my form, I have a TabControl with seven pages, each full of elements (TextBoxes and DropDownLists, primarily). I pull some information in with a DataReader, populate a DataTable, and use the elements' DataBindings.Add method to fill those elements with the current values.

    The user is able to enter data into these elements, press "Save", and I then set the parameters of an UPDATE query using the elements' Text fields. For instance:

    updateCommand.Parameters.Add("@CustomerName", SqlDbType.VarChar, 100).Value = CustomerName.Text;

    The problem I have is that once I load the form, all of the elements are apparently considered empty until I select each tab manually. Thus, if I press "Save" immediately upon loading the form, all of the fields on the TabPages that I have not yet selected try to UPDATE with empty data (not nice). As I select each TabPage, those elements will now send their data along properly. For the time being, I've worked out a (very) ugly workaround where I programmatically select each TabPage when the data is populated for the first time, but that's an unacceptable long-term solution.

    My question is, how can I get all of the elements on the TabPages to return their data properly before the user selects that TabPage?

    ANSWER:
    The issue is that the controls are not Created until the tab is displayed. One solution would be to actually create the controls on loading the page like so:

    private static void CreateControls( Control control )
    {
        CreateControl( control );
        foreach ( Control subcontrol in control.Controls )
        {
            CreateControl( subcontrol );
        }
    }
    private static void CreateControl( Control control )
    {
        var method = control.GetType().GetMethod( "CreateControl", BindingFlags.Instance | BindingFlags.NonPublic );
        var parameters = method.GetParameters();
        method.Invoke( control, new object[] { true } );
    }

    Then in the constructor on your form, you'd do something like:

    public Form()
    {
        CreateControls( this.tabPage1 );
    }

    This solution relies on the fact that there is an internal CreateControls method takes a single boolean parameter which will let you create the control even if it is not visible.
    -----------------------------------------------------------
    ho is correct; the elements on a TabPage are not created until that TabPage is selected. I just added a loop upon form load that selects each TabPage and now it works fine.

    foreach (TabPage tp in tabControl1.TabPages)
        {
            page.Show();
        }
    -----------------------------------------------------------
    I'm not sure if you can. The following is a quote from MSDN:

    "Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown."

    However, instead of having the update code get the values from the controls directly, maybe you could create a class that could hold that DataTable you use to populate the controls and then when the update code is called it asks the class for the value and the class checks if the control is loaded and otherwise it gets the value from the DataTable instead.
  • 相关阅读:
    一些鲜为人知的编程真相
    一些鲜为人知的编程真相
    Ruby 1.9不会杀死Python
    Boost.Asio和ACE之间关于Socket编程的比较
    Effective C++第17条:要在单独的语句中使用智能指针来存储由new创建的对象
    Ruby 1.9不会杀死Python
    Boost智能指针——weak_ptr
    对象生死劫 - 构造函数和析构函数的异常
    Protocol Buffers:Google 的数据交换格式
    根据出生日期计算年龄
  • 原文地址:https://www.cnblogs.com/luoyaoquan/p/2244841.html
Copyright © 2020-2023  润新知