C# 正在等待初始化控件

C# 正在等待初始化控件,c#,winforms,C#,Winforms,我的表单看起来有点像三个窗格的电子邮件客户端。左侧是一个网格,其中有一组人员。右上角是当前人员的详细信息记录。右下角是一个自定义控件,带有许多复选框,显示当前人员的专业领域: [x] 烹饪[x]擦窗[x]脑部手术 [x] 按摩疗法[x]唱歌[]随意破坏行为 打开表单时,焦点将转到表单左侧网格中列出的第一个人,并触发网格的“焦点行更改”事件。在该事件的处理程序中,我获取当前人员的id,然后从数据库中获取该人员的详细信息数据并填充详细信息记录,还获取该人员的专业领域行并设置复选框。除了第一次打开表单

我的表单看起来有点像三个窗格的电子邮件客户端。左侧是一个网格,其中有一组人员。右上角是当前人员的详细信息记录。右下角是一个自定义控件,带有许多复选框,显示当前人员的专业领域:

[x] 烹饪[x]擦窗[x]脑部手术

[x] 按摩疗法[x]唱歌[]随意破坏行为

打开表单时,焦点将转到表单左侧网格中列出的第一个人,并触发网格的“焦点行更改”事件。在该事件的处理程序中,我获取当前人员的id,然后从数据库中获取该人员的详细信息数据并填充详细信息记录,还获取该人员的专业领域行并设置复选框。除了第一次打开表单时,所有这些都可以正常工作,因为此时带有许多复选框的自定义控件尚未初始化。此时MyCustomControl为null

if (null != MyCustomControl)
{
  MyCustomControl.SetCheckedValues( datasource);
}
处理这种情况的最佳实践设计模式是什么?当我的控件尚未完全初始化时,我在这里做什么

if (null != MyCustomControl)
{
  MyCustomControl.SetCheckedValues( datasource);
} 
else 
{
  // ?? Wait around for a bit and keep trying every 100ms?
}

在一个子例程中执行UI初始化函数,该子例程在初始化所有其他UI元素后才会调用,或者根据后端值而不是UI进行计算



作为对评论和其他帖子的回应,如果您无法获得任何其他功能,您可以向UI添加一个“刷新”按钮,在一个子例程中执行UI初始化函数,该子例程在初始化所有其他UI元素后才会调用,或者根据后端值而不是UI进行计算



作为对评论和其他帖子的回应,如果您无法获得任何其他功能,您可以在UI中添加一个“刷新”按钮,据我所知,您正在设置MyCustomControl.SetCheckedValues(数据源)当焦点\u行\u更改时触发事件

当表单刚刚加载时也会发生这种情况,这通常是不需要的,因为当选定的索引仍然为-1时,会出现事件通知要加载的内容

我解决这个问题的方法是,我有一个名为
doneLoading
的全局布尔值。它以false开头,在调用Form_show()事件时变为true

在那里,我只在需要等待表单实际加载完成后才允许执行的任何代码段周围放置一个
if(doneLoading)
。就你而言,我会:

if(doneLoading)
{
MyCustomControl.SetCheckedValues( datasource);
}

据我所知,您正在设置
MyCustomControl.SetCheckedValues(数据源)当焦点\u行\u更改时触发事件

当表单刚刚加载时也会发生这种情况,这通常是不需要的,因为当选定的索引仍然为-1时,会出现事件通知要加载的内容

我解决这个问题的方法是,我有一个名为
doneLoading
的全局布尔值。它以false开头,在调用Form_show()事件时变为true

在那里,我只在需要等待表单实际加载完成后才允许执行的任何代码段周围放置一个
if(doneLoading)
。就你而言,我会:

if(doneLoading)
{
MyCustomControl.SetCheckedValues( datasource);
}

当我的控件出现此问题时,我在控件中解决此问题的方法是实施

在您的控制下,您可以放置以下内容:

public class MyCustomControl: ISupportInitialize
{
    private bool _initializing = false;

    private void BeginInit()
    {
        _initializing = true;
    }

    private void EndInit()
    {
        _initializing = false;
    }

    private void SomeMethodThatWouldRaiseAnEventDuringInit()
    {
        if (_initializing) return;
        //...
    }
}
windows窗体设计器将检查实现该界面的控件,并在
.designer.cs
文件中生成以下代码:

((System.ComponentModel.ISupportInitialize)(this.customControl1)).BeginInit();
///
/// customControl1
///
this.customControl1.SelectedIndex = 0;  //this would normally raise the event
((System.ComponentModel.ISupportInitialize)(this.customControl1)).EndInit();

当我的控件出现此问题时,我在控件中解决此问题的方法是实施

在您的控制下,您可以放置以下内容:

public class MyCustomControl: ISupportInitialize
{
    private bool _initializing = false;

    private void BeginInit()
    {
        _initializing = true;
    }

    private void EndInit()
    {
        _initializing = false;
    }

    private void SomeMethodThatWouldRaiseAnEventDuringInit()
    {
        if (_initializing) return;
        //...
    }
}
windows窗体设计器将检查实现该界面的控件,并在
.designer.cs
文件中生成以下代码:

((System.ComponentModel.ISupportInitialize)(this.customControl1)).BeginInit();
///
/// customControl1
///
this.customControl1.SelectedIndex = 0;  //this would normally raise the event
((System.ComponentModel.ISupportInitialize)(this.customControl1)).EndInit();

当焦点从一行移动到另一行时,包含人员列表的网格将触发一个焦点行更改事件。这是用户与之交互的UI,每当用户选择不同的人员时,必须获取人员详细信息记录和人员专业知识记录。我无法控制网格何时完成初始化。我希望避免使用“刷新”按钮,因为它要求用户知道数据需要刷新并采取措施。理想情况下,我希望找到一种方法,只有在慢速控件唤醒后,才能唤醒快速控件。我想让earlybird控制器呆在床上,让sleepyhead控制器醒来,对earlybird控制器说“起床,发光!”。我想sleepyhead控件可以在sleepyhead的InitializationComplete事件中将earlybird控件添加到窗体的控件列表中。re:当我的控件尚未完全初始化时,我该怎么办?您必须等待它完全初始化,然后刷新。当焦点从一行移动到另一行时,包含一个列表的网格会触发一个焦点行更改事件。这是用户与之交互的UI,每当用户选择不同的人员时,必须获取人员详细信息记录和人员专业知识记录。我无法控制网格何时完成初始化。我希望避免使用“刷新”按钮,因为它要求用户知道数据需要刷新并采取措施。理想情况下,我希望找到一种方法,只有在慢速控件唤醒后,才能唤醒快速控件。我想让earlybird控制器呆在床上,让sleepyhead控制器醒来,对earlybird控制器说“起床,发光!”。我想sleepyhead控件可以在sleepyhead的InitializationComplete事件中将earlybird控件添加到窗体的控件列表中。re:当我的控件尚未完全初始化时,我该怎么办?您必须等待它完全初始化,然后刷新。你的慢控能通知你的快控吗