私はレガシーWinForms MDIアプリケーションに取り組んでおり、子フォームを希望どおりに動作させるのに問題があります。私の目的は、子フォームを常に最大化することです(ドッキング)。
問題は、MaximizeBox
をfalse
に設定しても、最大化/サイズ変更ボタンがMDIツールストリップに表示され、ユーザーが子フォームのサイズを変更(ドッキング解除)できることです。これを回避する唯一の方法は、ControlBox
をfalse
に設定することですが、閉じるボタンが消えます(これは私が望んでいることではありません)。
固定のFormBorderStyle
を使用し、サイズ変更イベントが発生したときに子フォームを最大化しようとしましたが、どのアプローチも機能しませんでした。
私が見逃した超秘密の財産はありますか、それとも不可能ですか?
よろしくお願いいたします。
私は自分の子フォームを処理するための卑劣なメソッド(@rfresiaのおかげで)を書きました、それは同じ問題に遭遇する他の人を助けるかもしれません:
//All child forms derive from ChildForm
//Parent MDI Form implementation
//...
private void ShowForm(ChildForm form)
{
//Check if an instance of the form already exists
if (Forms.Any(x => x.GetType() == form.GetType()))
{
var f = Forms.First(x => x.GetType() == form.GetType());
f.Focus();
f.WindowState = FormWindowState.Maximized;
}
else
{
//Set the necessary properties (any other properties are set to default values)
form.MdiParent = this;
form.MaximizeBox = false;
form.MinimizeBox = false;
form.WindowState = FormWindowState.Maximized;
Forms.Add(form);
form.Forms = Forms;
form.Show();
form.Focus();
//Lets make it nasty (some forms aren't rendered properly otherwise)
form.WindowState = FormWindowState.Normal;
form.WindowState = FormWindowState.Maximized;
}
}
//...
//ChildForm implementation
//...
public List<Form> Forms { get; set; }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
Forms.RemoveAll(x => x.GetType() == GetType());
}
protected override void OnResize(EventArgs e)
{
WindowState = FormWindowState.Maximized;
}
最小化しないようにする各子フォームのOnResizeをオーバーライドできます。または、BaseFormを作成し、そこからすべての子フォームを継承します。
protected override void OnResize(EventArgs e)
{
this.WindowState = FormWindowState.Maximized;
}
また、X、y座標を使用できますが、OnResizeで十分です。これを子フォームコンストラクターに入れます。
this.WindowState = FormWindowState.Maximized;
Point NewLoc = Screen.FromControl(this).WorkingArea.Location;
//Modifiy the location so any toolbars & taskbar can be easily accessed.
NewLoc.X += 1;
NewLoc.Y += 1;
this.Location = NewLoc;
Size NewSize = Screen.FromControl(this).WorkingArea.Size;
//Modifiy the size so any toolbars & taskbar can be easily accessed.
NewSize.Height -= 1;
NewSize.Width -= 1;
this.Size = NewSize;
this.MinimumSize = this.Size;
this.MaximumSize = this.MinimumSize;
ここからX、Yのコードを取得しました: http://bytes.com/topic/c-sharp/answers/278649-how-do-i-prevent-form-resizing
問題を解決するのは簡単ではありませんでしたが、私は誤って答えを見つけました。それは非常に簡単です。子フォームのwindowstateをデフォルトでNormalに設定します。次に、子ウィンドウのウィンドウ状態を必ずリセットしてください[〜#〜] after [〜#〜]Show()
メソッドを呼び出します。
例:
private void ShowNewForm(object sender, EventArgs e)
{
Form childForm = new Form();
childForm.MdiParent = this;
childForm.Text = "Window " + childFormNumber++;
childForm.Show();
childForm.WindowState = FormWindowState.Maximized;
}
form1 obj = new form1 ();
obj.MdiParent = MDIGracular.ActiveForm;
obj.StartPosition = FormStartPosition.CenterParent;
obj.WindowState = FormWindowState.Minimized;
obj.Dock = DockStyle.Fill;
obj.Show();
obj.WindowState = FormWindowState.Maximized;
これは私が同じ問題を克服した方法であり、コードをどこで見つけたか思い出せません。
private const int WM_SYSCOMMAND = 0x112;
private const int SC_MINIMIZE = 0xF020;
private const int SC_MAXIMIZE = 0xF030;
private const int SC_CLOSE = 0xF060;
private const int SC_RESTORE = 0xF120;
protected override void WndProc(ref Message msg)
{
if ((msg.Msg == WM_SYSCOMMAND) &&
(((int)msg.WParam == SC_MINIMIZE) || ((int)msg.WParam == SC_MAXIMIZE) ||
((int)msg.WParam == SC_CLOSE)) || ((int)msg.WParam == SC_RESTORE))
{
//do nothing
} // end if
else
{
base.WndProc(ref msg);
} // end else
}
私のアプリでは、これらの2行だけをフォームロードイベントに入れると機能することがわかりました。基本的な考え方をありがとうsarvjeet。あなたのために+1
this.WindowState = FormWindowState.Minimized;
this.WindowState = FormWindowState.Maximized;