現象
以下のシナリオについて考えてみます。
.NET デスクトップ アプリケーションは、Windows フォーム または Windows Presentation Foundation (WPF) を使用して作成されます。
アプリケーションは、
ShowDialog()
メソッドを使用して、別のウィンドウが所有するモーダル ダイアログを表示します。アプリケーションでは、
ShowInTaskbar
プロパティの値をtrue
に設定して、両方のウィンドウのタスク バー ボタンを作成します。Note
プロパティ値が
true
されている場合、ウィンドウにはタスク バー ボタンがあります。 既定値はtrue
です。
このシナリオでは、所有者ウィンドウをアクティブにするには、関連付けられているタスク バー ボタンを選択します。 ただし、モーダル ダイアログの所有者ウィンドウをアクティブにすると、一部のアプリケーションで予期しない動作やクラッシュが発生する可能性があります。これは、モーダル ダイアログが閉じるまで、所有者ウィンドウが非アクティブで無効なままである必要があるためです。
解決方法
状況に対応する次の方法を使用して、トップレベル ウィンドウと所有ウィンドウを含むウィンドウ所有権グループ内のウィンドウに 1 つのタスク バー ボタンを作成します。
System.Windows.Forms.Form
オブジェクトを使用して所有者ウィンドウでモーダル ダイアログを表示する場合は、ShowDialog
メソッドを呼び出す前に、Form オブジェクトのShowInTaskbar
プロパティ値をfalse
に設定します。System.Windows.Window
オブジェクトを使用して、所有者ウィンドウでモーダル ダイアログを表示する場合は、ShowDialog
メソッドを呼び出す前に、Window オブジェクトのShowInTaskbar
プロパティ値をfalse
に設定します。
次に、タスク バー ボタンが選択されると、システムによって所有権グループ内の正しいウィンドウがアクティブ化されます。
詳細
次の例では、Windows フォームを使用した .NET 6 デスクトップ アプリケーションでのこの解決方法を示します。
namespace WinFormsApp1
{
internal static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.Run(new Form1());
}
}
public class Form1 : Form
{
public Form1()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.button1.Location = new System.Drawing.Point(20, 20);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(200, 34);
this.button1.TabIndex = 0;
this.button1.Text = "Form2.ShowDialog";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.Button1_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private void Button1_Click(object? sender, EventArgs e)
{
Form2 form = new Form2();
form.Owner = this;
form.ShowInTaskbar = false;
form.ShowDialog();
}
private Button button1;
}
public class Form2 : Form
{
public Form2()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.button1.Location = new System.Drawing.Point(20, 20);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(200, 34);
this.button1.TabIndex = 0;
this.button1.Text = "Form3.ShowDialog";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.Button1_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Name = "Form2";
this.Text = "Form2";
this.BackColor = System.Drawing.Color.Aqua;
this.ResumeLayout(false);
}
private void Button1_Click(object? sender, EventArgs e)
{
Form3 form = new Form3();
form.Owner = this;
form.ShowInTaskbar = false;
form.ShowDialog();
}
private Button button1;
}
public class Form3 : Form
{
public Form3()
{
this.SuspendLayout();
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Name = "Form3";
this.Text = "Form3";
this.BackColor = System.Drawing.Color.Olive;
this.ResumeLayout(false);
}
}
}