2010-12-13 42 views
8

C#.NET MDIには2つの問題があります。バグhereを再現するVS2010ソリューションをダウンロードできます。C#.NET MDIのバグは、プログラムで最大化された子フォームを非表示にして表示し、最大化すると子フォームのアイコンを変更できない場合です。

1)最大化された子フォームをプログラムで隠して表示すると、再び最大化されず、最大化されず、通常の状態にもなりません。

子フォームが最大化されるとprogramicaly隠されて、再び示され、そして、それは(メニューバーに気づくください - 子フォームのコントロールボックスが表示されますが、子フォームが最大化されていない)、このようなものになり
childForm = new Form(); 
childForm.Text = "Child Form"; 
childForm.MdiParent = this; 

... 

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = true; 
} 

... 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = false; 
} 

alt text

この段階では、子フォームを移動することはできません。しかし、ダミーの子フォームを表示して隠すだけで、実際の子フォームが適切に最大化されるようにすることで回避策を見つけました。しかし、これはMDI領域をちらつくようにします。メソッドを無効化、更新、更新しようとしましたが、役立たないことがあります。おそらく、このバグを克服し、ダミーの子フォームでMDI領域がちらつくのを防ぐための他の回避策がありますか?

private void workaround1Button_Click(object sender, EventArgs e) 
{ 
    dummyForm.Visible = true; 
    dummyForm.Visible = false; 
} 

2)子フォームが最大化されると、子フォームのアイコンがメニューバーに表示されます。ただし、子フォームが最大化されているときにアイコンを変更する必要がある場合、メニューバーのアイコンは更新されません(上記の画像を参照)。基本的にメニューバーを隠して表示する回避策も見つけました。アイコンがリフレッシュされますが、メニューバーの下のすべてが点滅します。メソッドを無効化、更新、更新しようとしましたが、役立たないことがあります。子フォームのアイコンを更新するためのメニューバーを作成する他の方法はありますか?また

private void workaround2Button_Click(object sender, EventArgs e) 
{ 
    menuStrip.Visible = false; 
    menuStrip.Visible = true; 
} 

私は親フォームが通常のウィンドウ状態モードのときに気づい(最大化されていない)、あなたは1つのピクセルで、フォームの幅や高さを変更する、それがあるべきとして子フォームが最大となると、メニューバーの子フォームのアイコンが適切に更新され、上記の他の回避策は必要ありません。プログラマティックなフォームのサイズを変更すると、1ピクセルずつちらつきが発生し、親フォームが最大化されたときにはできません。フォームのサイズを変更し、子フォームが正しく最大化され、メニューバーのアイコンがリフレッシュされるときに呼び出される再描画/更新機能を呼び出す方法はありますか?

答えて

1

これらのバグを回避する方法が見つかりました。

まず、フォームとその子のためにペイントを中断する必要があります。私は非常に有用なスレッドhereを見つけました。これには、それを行う方法が記載されています。

ペイントを中断した後、コントロールのUpdateBoundsメソッドを呼び出して、ClientRectangleの幅または高さを1つ増やしてから、以前と同じ値に戻します。これにより、すべてを更新/再描画するレイアウト機能が呼び出されます。最後のステップは、ペイントを有効にすることです。私が推測することはあまり良いソリューションではありませんが、それは動作します。

StopDrawing(); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1); 
StartDrawing(); 

私はよりスムーズGUIを動作させるために、これらの2個のバグを回避作業のため、だけでなく、一般的にだけでなく、絵は非常に有用中断見つけます。私はこれが何らかのちらつきを取り除くのを助けることができると思う。しかし、この解決策にはP/Invokesが必要であり、これは一般的に避けなければならない。

1

表示をtrue/falseに設定する代わりに、非表示/表示を使用するのに疲れましたか?

試してみてください。

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Show(); 
} 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Hide(); 
} 
+0

はい、私が試してみましたが、何も変わりません。私はchildForm.Visible = true/falseがそれらのメソッドを呼び出すと思います。 – Povilas

+1

実際には、それは逆になるはずです。非表示/表示は、表示をfalse/trueに設定する必要があります。 –

1

内部MdiControlStripクラスの実装のバグ、アイコンと親ウィンドウ内の最小/最大/復元のグリフを表示するコントロールがあります。私はそれをまだ特徴づけていませんが、コードはそれほど簡単ではありません。このバグの古典的な副作用は、グリフが2倍になり、他の副作用が見つかったということです。修正は簡単ですが、コンストラクターが完了するまで子ウィンドウを作成するのが遅れます。このように:

public MainForm() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnLoad(EventArgs e) { 
     childForm = new Form(); 
     childForm.Text = "Child Form"; 
     childForm.MdiParent = this; 

     dummyForm = new Form(); 
     dummyForm.MdiParent = this; 
     dummyForm.WindowState = FormWindowState.Maximized; 
     base.OnLoad(e); 
    } 
+0

ああ、はい、Loadイベントを使用しました。 base.OnLoad()を下に移動します。私のマシン™で動作します。 –

+0

OnLoadメソッドをオーバーライドして修正を試みましたが、同じバグの動作が残ります。何も変わりません。子フォームは動的に作成する必要があるため、これは私にとっては解決策ではありません。 – Povilas

1

この回避策はどうですか。

UPDATE

私はちょうどあなたが何ができるかのアイデアを与えました。上記と同じアイデアを使用すると、Windowsの状態を保存する新しい基本形式になります。下記参照。 Formの代わりにFixedFormからフォームを派生させてください。

public partial class FixedForm : Form 
{ 
    private FormWindowState lastWindowState; 

    public FixedForm() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnVisibleChanged(EventArgs e) 
    { 
     base.OnVisibleChanged(e); 

     if (Visible) 
     { 
      WindowState = lastWindowState; 
     } 
     else 
     { 
      lastWindowState = WindowState; 
      WindowState = FormWindowState.Normal; 
     } 
    } 
} 
+0

これはバグを克服する方法の可能性の1つですが、子フォームのアニメーションを最大限に繰り返して繰り返し表示するようにしていますが、ちょっと迷惑です。私の回避策は速いです。 – Povilas

+0

ちらつきなしで私の更新を確認してください – Scoregraphic

+0

これが問題を解決すれば、親ウィンドウハンドルに 'WM_SIZE'メッセージを送ることができます。 – Scoregraphic

0

理由だけではなく、手動でウィンドウを作成した後、menuStrip項目に必要なアイコンをリセットしない:

menuStripMain.Items[0].Image = null; 
関連する問題