【发布时间】:2013-06-07 03:34:44
【问题描述】:
使用此代码:
using (pbDialog = new pbDialogs())
{
ProgressBar = new frmProgress(this, false);
ProgressBar.SetProgressLabelText("Inventory Data");
MessageBox.Show("Set progress label text to Inventory data");
typeProgress = (int) ProgressStates.ProgressQRY;
ProgressBar.label1.Text += " (Receiving)";
if (pbDialog != null)
{
MessageBox.Show("pbDialog is not null");
//pbDialog.ShowDialog(ProgressBar, this);
}
else
{
MessageBox.Show("pbDialog IS null");
ProgressBar.ShowDialog();
}
ProgressBar = null;
MessageBox.Show("Made it to compressDB()");
compressDB();
. . .
}
我看到“将进度标签文本设置为库存数据” 那么“pbDialog 不为空” 然后“压缩DB()”
那里没什么奇怪的;但是如果我取消注释上面注释的行,我只会看到“pbDialog is not null”
由于对 ShowDialog() 的调用,它因某种原因挂起;不过,真正奇怪的是,这会阻止显示“将进度标签文本设置为库存数据”。为什么会这样?
注意:我认为代码中的“pb”代表“花生脆”之类的;无论如何,我很确定“脆弱”部分。
更新
是的,将 ShowDialog() 与 pbDialog 结合使用是原始编码员默默无闻地练习工作保障的众多示例之一 - 但后来他 [un] 幸运的是,在他身后留下了一堆意大利面条/蛋壳代码没有 cmets、误导性的名称以及在女巫酿造中可以想象到的各种奇怪、令人费解、违反直觉的做法,据称他认为这是优雅设计和巧妙技巧的杰作。
pbDialog 是一个类 (pbDialogs) 的实例。只是为了让您体验一下这一切是多么令人毛骨悚然、令人费解和纠缠不清,这是那堂课:
public class pbDialogs : IDisposable
{
private static Form m_top;
public pbDialogs()
{
} // pbDialogs Constructor
public static void Activate( Form form )
{
form.Capture = true;
IntPtr hwnd = OpenNETCF.Win32.Win32Window.GetCapture();
form.Capture = false;
OpenNETCF.Win32.Win32Window.SetForegroundWindow( hwnd );
} // Activate
/// <summary>
/// This method makes ShowDialog work the way I want, I think.
/// </summary>
/// <remarks>
/// Here is what it does:
/// 1. Sets the caption of the new window to the same as the caller's.
/// 2. Clears the caption of the parent so it won't show up in the task list.
/// 3. When the ShowDialog call returns, brings the previous window
/// back to the foreground.
/// </remarks>
/// <param name="dialog"></param>
/// <param name="parent"></param>
public void ShowDialog( Form dialog, Control parent )
{
Control top = parent.TopLevelControl;
string caption = top.Text;
dialog.Text = caption;
top.Text = "--pending--"; // Don't show parent in task list
dialog.Activated += new EventHandler( form_Activated );
dialog.Closed += new EventHandler( form_Closed );
m_top = dialog; // New top-most form
dialog.ShowDialog();
m_top = (Form)top; // The top dialog just changed
dialog.Activated -= new EventHandler( form_Activated );
dialog.Closed -= new EventHandler( form_Closed );
top.Text = caption; // Make visible in task list again
Activate( (Form)top ); // And make it the active window
} // ShowDialog
/// <summary>
/// If one of our other windows, such as the main window,
/// receives an activate event, it will activate the current
/// top-most window instead.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void form_Activated( object sender, EventArgs e )
{
if( (m_top != null) && !(sender == m_top) ) // Is this the top-most window?
Activate( m_top ); // No, activate the top dialog
} // form_Activated
private static void form_Closed( object sender, EventArgs e )
{
m_top = null; // When you close the top dialog, it's not top anymore
} // form_Closed
#region IDisposable Members
public void Dispose()
{
// TODO: Add pbDialogs.Dispose implementation
}
#endregion
} // class pbDialogs
还有一个“相关的”ProgressBar——一种与 pbDialogs 共享文件的表单,其实例变量在包含上述代码的文件中定义:
public static frmProgress ProgressBar;
这绝对是“打地鼠”的代码 - 如果我做出一个看似无害的小改动,整个达拉斯都会崩溃,即使是半理智的人也会认为代码中完全不相关的部分。
这可能表明此代码/项目是多么松散:我将在注释掉几行后新建一个版本,文件大小将从 400KB 更改为 408,或从 412 更改为 408 ,等等。对于一个 .exe 来说,通过这么小的变化来改变这么大的大小(在相对意义上)是不正常的行为,是吗?
更新 2
这在 frmProgress(同时具有“public class frmProgress : System.Windows.Forms.Form”和“public class pbDialogs : IDisposable”)让我害怕:
using System.Windows.Forms;
using OpenNETCF.Windows.Forms;
第二个(OpenNETCF)是灰色的,表示它并没有真正使用,但可能是它以前被使用过,并且不知何故“Windows.Forms”代码无意中切换到了“System”代码,这可能是促成了它目前的古怪。
【问题讨论】:
-
是Debug还是Release代码?
-
似乎
pbDialog可能在代码继续之前等待某种输入。但奇怪的是它会阻止以前的MessageBox显示...... -
pbDialog到底是什么?标准的 Form.ShowDialog 没有那个签名(它可以只带一个参数,也可以不带)。 -
@Matt Seiker:我在上面以一种相当冗长、恼怒和刻薄的方式回答你的问题。
-
@Evan:这段代码在过去是有效的(尽管它很不稳定,就像一个蹒跚学步的字母积木塔)。