web-dev-qa-db-ja.com

Winformsコントロールを前面に表示

Control.BringToFront()以外にコントロールを前面に表示する方法はありますか?ユーザーコントロールに一連のラベルがあり、そのうちの1つを前面に表示しようとしても機能しません。私はすべてのコントロールをループして、興味のあるものを除いてすべて送り返しましたが、それによって状況が変わることはありません。

ラベルをユーザーコントロールに追加する方法は次のとおりです

private void AddUserLabel()
{
    UserLabel field = new UserLabel();
    ++fieldNumber;

    field.Name = "field" + fieldNumber.ToString();         

    field.Top = field.FieldTop + fieldNumber;
    field.Left = field.FieldLeft + fieldNumber;
    field.Height = field.FieldHeight;
    field.Width = field.FieldWidth;
    field.RotationAngle = field.FieldRotation;
    field.Barcode = field.BarCoded;
    field.HumanReadable = field.HumanReadable;
    field.Text = field.FieldText;
    field.ForeColor = Color.Black;

    field.MouseDown += new MouseEventHandler(label_MouseDown);
    field.MouseUp += new MouseEventHandler(label_MouseUp);
    field.MouseMove += new MouseEventHandler(label_MouseMove);

    userContainer.Controls.Add(field);

    SendLabelsToBack(); //Send All labels to back

    userContainer.Controls[field.FieldName].BringToFront();
}

以下は、それらすべてを背面に送る方法です。

private void SendLabelsToBack()
{
    foreach (UserLabel lbl in userContainer.Controls)
    {
        lbl.SendToBack();
    }
}
18
Nathan

ええ、別の方法があります。 Controls.SetChildIndex()もZオーダーを変更します。インデックス0のものが上にあります。ただし、何も購入しません。BringToFront()はこのメソッドを使用します。

与えられたSendLabelsToBack()メソッドは機能しません。また、追加されたラベルを背面に送信します。しかし、あなたの次のステートメントはそれを再び修正します。

これは機能しません。つまり、BringToFront()メソッドは実行されません。 「最初のチャンスの例外」通知を出力ウィンドウで確認します。書かれているように、ユーザーコントロールにUserLabel以外のコントロールが含まれている場合、SendLabelsToBack()は例外を発生させます。また、ブレークポイントafterBringToFront()コールを設定し、ブレーク時にuserContainer.Controls[0].Nameの値を確認します。

22
Hans Passant

コントロールのz-indexはコンテナーごとです。

コンテナー内のコントロール(Panelなど)でBringToFrontを呼び出しても、コンテナーは前面に移動しません。
そのため、コントロールはそのコンテナ内の他のコントロールの前にのみ配置されます。

コントロールがどのコンテナーにあるかを確認するには、[表示]メニューの[ドキュメントアウトライン]ペインを使用できます。

[〜#〜] edit [〜#〜]userContainerコントロールはおそらく別のコントロールの背後にあります。

6
SLaks

Invalidate()の後にBringToFront()を試しましたか? BringToFrontがPaintイベントを発生させない

これを試して:

private void SendLabelsToBack()
{
    foreach (UserLabel lbl in userContainer.Controls)
    {
        lbl.SendToBack();
        lbl.Invalidate();
    }
}
5
Patrick

最後の行を変更する必要があるだけだと思います。

userContainer.Controls[field.FieldName].BringToFront(); 

これに:

userContainer.Controls[field.Name].BringToFront(); 

Controlsコレクションのインデクサーとして文字列を使用すると、文字列は(Nameプロパティではなく)コントロールのFieldNameプロパティによって使用されます。

最近追加したコントロールを一番上に配置しようとしているだけなので、これも機能します。

userContainer.Controls[userContainer.Controls.Count - 1].BringToFront();
3
MusiGenesis

私の経験から、Windowsは1つのグラフィックコンテナー(ペイン、グループボックスなど)に属するすべてのコントロールをソフトウェアコレクションに配置するように見えます。コレクションは、そのコンテナ内のすべてのコントロールのプロパティである子インデックスによって並べ替えられます。秘訣は、同じインデックスを持つ子供が存在できること、そして存在することです。この場合、ウィンドウは他の子に対して相対的に順序付けられた子をペイントしますが、それらの間では、コンテナに追加された順序とは逆の順序でそれらをペイントします。

簡単に言えば、1つのコンテナの場合、Zオーダーを変更する場合は、一部のインデックスだけでなくすべてを変更して、コントロールに異なるインデックスを設定する必要があります。例えば:

_foreach (Control newControl in TopControl.Controls)
{
   TopControl.Controls.SetChildIndex(newControl,indexlogic(newControl));
}
_

ここで、indexLogic(newControl )は、特定のコントロールのインデックスを計算する方法です。

0
Gogu CelMare