2011-03-28 76 views
1

我的表单看起来像一个三窗格的电子邮件客户端。左侧是一个包含人员列表的网格。右上角是当前人的详细记录。右下是许多复选框显示专长的当前人的领域自定义控件:等待控件初始化

[X]烹饪[X]擦窗[X]脑外科

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

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

if (null != MyCustomControl) 
{ 
    MyCustomControl.SetCheckedValues(datasource); 
} 

什么是处理这种情况的最佳实践设计模式?当我的控制没有完全初始化时,我在这里做什么?

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

你能详细了解MyCustomControl何时被初始化以及初始化依赖于什么? – Yetti 2011-03-28 17:53:20

回答

0

做的那个不叫直到所有其他UI元素初始化子程序你的UI初始化函数,或立足于后端值,而不是用户界面中的计算。


响应意见和其他职位,如果你不能让别的工作,你可以添加一个“刷新”按钮,将UI

+0

包含列表的人员在每次焦点逐行移动时都会触发焦点行更改的事件。这是用户与用户交互的用户界面,只要用户选择不同的人,就必须提取人员详细记录和人员专业知识记录。我无法控制网格完成初始化的时间。 – Tim 2011-03-28 16:41:18

+0

我希望避免刷新按钮,因为它需要用户知道数据需要刷新并采取行动。理想情况下,我想找到一种快速控制只有在慢速控制唤醒后才能唤醒的方法。我想让早起的鸟儿控制住在床上,并希望昏昏欲睡的控制唤醒并说“上升和发光!”到早期的鸟类控制。我想sleepyhead控件可以将earlybird控件添加到sleepyhead的InitializationComplete事件中的表单控件列表中。 – Tim 2011-03-30 16:19:41

+0

re:当我的控件尚未完全初始化时,我在这里做什么?你必须等到它完全初始化,然后刷新。完成后,您的慢速控制能否通知您的快速控制? – Beth 2011-03-30 17:18:33

0

据我所知,您是在设置MyCustomControl.SetCheckedValues(datasource);当focused_row_changed事件触发时。

当表单刚刚加载时,这通常也是不希望发生的,因为最终会出现事件,例如,当选定的索引仍然为-1时,会加载事件。

我一直在解决这个问题的方法是我有一个名为doneLoading的窗体的全局布尔值。它从false开始并在调用Form_Shown()事件时变为true。

从那里我只是把一个if(doneLoading)围绕任何代码片段,需要等待,直到表单实际完成加载之前,它被允许执行。在你的情况,我会做:

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

在Form_Shown()事件中,我必须手动将人员网格中的焦点设置为第一行。但重点已经放在第一行,因此焦点行改变的事件不会触发。所以我不得不手动启动获取person-detail-record和person-expertise-record的例程,在你知道它之前,它不再是一个事件驱动的程序,而是事件驱动的编码和好的组合旧式结构化编码。这就是我想要避免的,尽管也许不可能避免它。 – Tim 2011-03-28 16:47:38

+0

@Tim - 我不确定我是否理解这个问题,或者可能是理想的行为。当表单首次打开时,是否希望MyCustomControl被填充,或者是否希望等到用户有意选择了某个人?如果是后者,那么这就是我的答案将促成的。我的答案中的代码所做的是禁止调用SetCheckedValues()方法,直到表单完成加载。换句话说,您只需将我放在那里的代码放入以前的任何事件中,并且它应该只在*表单完全加载之前更改整体行为。 – Yetti 2011-03-28 17:00:35

+0

当窗体被加载时,控制器列表被填充了人名和ID,并且焦点被设置(自动)到导致其Focused_Row_Changed事件触发的第一行。在该事件的处理程序中,我获取关注人员的ID并从数据库获取详细数据。但表单上的另一个控件尚未准备好接收该数据。我的控制器列表比从其接收数据的控制器更快地初始化。目前,我的经销商不断敲门,直到它接近门,可以这么说:“控制先生的数据传送!” – Tim 2011-03-30 16:13:22

1

我在我的控制解决了这个时候,他们有过这样的问题,是贯彻落实ISupportInitialize的方式。

在你的控制,你会放像:

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(); 
+0

这是进入快速控制还是慢速控制?我不确定它会如何工作。我的slowpoke控件只是显示一些发送给它的数据,但是从数据库中获取数据的控件被初始化,并且比显示数据的控件更快地填充。有没有办法延迟更快控制的初始化,直到slowpoke控制完成初始化之后? – Tim 2011-03-30 16:16:27