• 締切済み

C#でパネルに子パネルを上から降順追加したいです。

図のように"追加ボタン"を押すと親パネル(panel1)に子パネル(panel2)を上から 追加する画面を作りました。(以下がソースです) private void button1_Click(object sender, EventArgs e) { int i = 0; foreach (Panel p in panel1.Controls) { i++; p.Top += 40; } Panel panel2 = new Panel(); createPanel(panel2, i);※子パネルのレイアウトを設定し、確認用の連番をセットしています panel1.Controls.Add(panel2); } 常に親パネルの最上段に子パネルを追加したいのですが、 スクロールバーで親パネルの下のほうで追加ボタンを押すと、 親パネルの表示されている最上段の位置に子パネルが追加されてしまいます。 スクロールバーで親パネルの最下部に移動していても、追加するときは親パネルの(0,0,)の位置に 子パネルを表示させるにはどのように実装したらよいでしょうか? メソッドcreatePanel(panel2, i)の中で、 子パネルのロケーションを0,0に設定してもダメでした。 以上、よろしくお願いいたします。

みんなの回答

回答No.1

まず,親パネルのかわりにFlowLayoutPanellを使って下さい。 この時, ・FlowDirectionをTopDownにする →内部のコントロールを上端から下に並べる ※BottomUpは下端から上に並べていく ・WrapContentsをFalseにする →コントロールが入りきらない場合にコントロールを折り返して配置させない ・AutoScrollをTrueにする →コントロールが入りきらない場合にスクロールバーを表示する という設定が必要になります。 次に,基本的にはコントロールをControls.Addで追加していくのですが, 上記のプロパティからわかるように,単純に追加すると一番下に追加されます。 これを避けるために,Controls.AddのあとにControls.SetChildIndexでnewIndexに0を指定し, 追加したコントロールを一番上になるようにします。 最後に,幅の調整です。 Dock系による調整が出来ないので,丁度の幅にするには FlowLayoutPanelのClientSize.Widthから追加したコントロールのMargine.Horizontalを引くことで出せますが, これだけだとスクロールバーが表示されたタイミングで幅がずれます。 いくつか試したところ, 1. FlowLayoutPanelをSuspendLayoutする 2. FlowLayoutPanelのAutoScrollをfalseにする 3. FlowLayoutPanelの全ての子コントロールの幅を調整する 4. FlowLayoutPanelのAutoScrollをtrueにする 5. FlowLayoutPanelをResumeLayoutする でできました。 以下,TextBoxを追加していくサンプル (C# on .NET Framework 4) です。 ・FlowLayoutPanel型のコントロールflowLayoutPanel1 ・Button型のコントロールbutton1 を置き, ・button1.Clickイベントにbutton1_Click ・flowLayoutPanel1.ResizeイベントにflowLayoutPanel1_Resize を設定しています。 また,_をスペースに,もしくは____をタブに変換してください。 private void button1_Click (object sender, EventArgs e) { ____var textBox = new TextBox() { Text = flowLayoutPanel1.Controls.Count.ToString() }; ____flowLayoutPanel1.Controls.Add(textBox); ____flowLayoutPanel1.Controls.SetChildIndex(textBox, 0); ____ResetChildSize(); } private void flowLayoutPanel1_Resize (object sender, EventArgs e) { ____ResetChildSize(); } private void ResetChildSize () { ____flowLayoutPanel1.SuspendLayout(); ____flowLayoutPanel1.AutoScroll = false; ____foreach (var control in flowLayoutPanel1.Controls.Cast<Control>()) ____{ ________control.Width = flowLayoutPanel1.ClientSize.Width - control.Margin.Horizontal; ____} ____flowLayoutPanel1.AutoScroll = true; ____flowLayoutPanel1.ResumeLayout(); } ところで,子パネルはユーザーコントロール化できないのですか。 Panelよりも色々と便利なことが多いですけれども……。

関連するQ&A

  • C# パネルの中にボタンを動的に配置したいです

    C# でフォームの中にパネルを置き、そのパネルの中に、ボタンを動的に配置したいです。 以下のページにあるようなことを、パネル内にしたいです。 動的にコントロールの配列を作成する http://dobon.net/vb/dotnet/control/buttonarray.html ---------------------- [C#] //ボタンコントロール配列のフィールドを作成 private System.Windows.Forms.Button[] testButtons; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //ボタンコントロール配列の作成(ここでは5つ作成) this.testButtons = new System.Windows.Forms.Button[5]; //ボタンコントロールのインスタンス作成し、プロパティを設定する this.SuspendLayout(); for (int i = 0; i < this.testButtons.Length; i++) { //インスタンス作成 this.testButtons[i] = new System.Windows.Forms.Button(); //プロパティ設定 this.testButtons[i].Name = "Button" + i.ToString(); this.testButtons[i].Text = i.ToString(); this.testButtons[i].Size = new Size(30, 30); this.testButtons[i].Location = new Point(i * 30, 10); //イベントハンドラに関連付け this.testButtons[i].Click += new EventHandler(this.testButtons_Click); } //フォームにコントロールを追加 this.Controls.AddRange(this.testButtons); this.ResumeLayout(false); } //Buttonのクリックイベントハンドラ private void testButtons_Click(object sender, EventArgs e) { //クリックされたボタンのNameを表示する MessageBox.Show(((System.Windows.Forms.Button) sender).Name); } ----------------------------- プログラムの初心者です。宜しくお願いいたします。

  • C# panelのなかのpctureBox

    panel1のなかのpictureBox1 QNo.8077421の続き http://okwave.jp/qa8077421.html Form1にPicturBox1をはりつけてダブルクリックでイベントハンドラを作る Properties.Resources.IconH;は、*.bmp private void pictureBox1_Click(object sender, EventArgs e) { pictureBox1.Image = Properties.Resources.IconH; } これは、OK private void pictureBox1_Click(object sender, EventArgs e) { int a = 1; Control c = this.Controls["PictureBox"+a.ToString()]; ((PictureBox)c).Image = Properties.Resources.IconH; } これも、OK ここからがうまくいきません。 panel1を貼り付けPicturBox1をpanel1のなかに。 pictureBox1.Image = Properties.Resources.IconH; これは、OK ここからです。 int a = 1; Control c = this.Controls["PictureBox"+a.ToString()]; ((PictureBox)c).Image = Properties.Resources.IconH; これは、 NG NullReferenceException はハンドルされませんでした。 オブジェクト参照がオブジェクト インスタンスに設定されていません。 ((PictureBox)c).Image = Properties.Resources.IconH;これ これをつかいたい。 アドバイスをお願いできませんでしょうか。

  • コントロールパネルに追加

    WindowsXPでコントロールパネルに設定アイコンの追加などはできないでしょうか?

  • コントロールパネルから言語の追加ができない。

    コントロールパネルから言語の追加ができない。 キーボードの変更をクリックして追加から言語を選んでもOKボタンが表示されなくて、キャンセルボタンだけがクリックできる状態です。 どうしてなのか教えてください。

  • パネルをスクロールするには?

    パネルをスクロールしたいのです。 ・パネルは高さが条件によって変わります。 ・スクロールは縦です。 以上の事を踏まえて、パネルにスクロールバーを追加しました。しかし、スクロールしてもパネルが上下に動きません・・・ パネルを動かすために必要な事を教えてください。 Scrollbar scrollbar = new Scrollbar(); this.add(scrollbar, null); scrollbar.setBounds(new Rectangle(220, 15, 15, 180)); 以上の事で追加はできたのですが、パネルと連動するにはどんな制御が必要でしょうか?

    • ベストアンサー
    • Java
  • C# 多くのコントロールを持つPanelの作り方?

    FormにPanelを作ります Panelの面積を10cm×10cmと仮定します このPanelに100ケのRadio釦を貼り付けます ですからPanelが必要とする面積は相当なものになります 10ケ程度は上から下に順次貼り付けられますが、11ヶ目からは表示されているPanelの下限になってしまいPanelの枠内に入れられません ・Panelの下限を下にドラッグして下方向に延しましたがVisual Studio自体の画面デザインのサイズまでしか拡がりません ・AutoScrollをTrueにしてみましたが、FormデザインのPanel自体にはスクロールバーは表示されませんので、11ヶ目以降の貼付けスペースを見出せません どのようにしたら表示されているPanelの下限よりも遥か下までコントロールを貼り付けることが出来ますか? 色々と操作してみましたが分かりません? この操作方法をご存知でしたらお教え願います

  • windowsの設定などの画面について

    コントロールパネル等で、Windowsの設定を変更しようとしても、文字が大きくまた、スクロールバーが見当たならないため、ボタンを押そうにも、隠れて見えない状態になっています。 対処法を教えてください

  • タッチパネルのスクロールとマウス

    Windows 8です。コントロールパネルのハードウェアとサウンドのマウスプロパティでタッチパネルのスクロールを設定したのですがタッチパネルは動くのですがスクロールが動きません。スクロールするにはどうすればいいでしょうか?回答お願いします。

  • toolStripStatusLabelの書き換えでpanelのスクロール位置が変化

    こんにちは。 Windows Vista Home Premium VC# 2008 Express Edition を使用しています。 dataGridView.SelectionChangedイベントによるtoolStripStatusLabel.Textの書き換え時に予期しない動作をするため困っています。 【詳細】 まずフォームのコントロールをドキュメントアウトライン風に表すと Form ┣ panel ┃ ┗ dataGridView ┗ statusStrip   ┗ tolStripStatusLabel このような状態にします。 そして、panelのAutoScrollプロパティをtrueに、dataGridViewのサイズをpanelよりも大きくします。 最後に、dataGridViewのSelectionChangedイベントにtoolStripStatusLabelのTextプロパティを書き換えるメソッドを追加します。 この状態で、垂直方向のスクロール位置が0より大きい時にdataGridViewのセルを選択すると、そのたびにpanelのスクロール位置が垂直・水平共にdataGridViewの0,0の位置になってしまいます。 これの原因と対処法をご存知の方がいらっしゃいましたら教えてください。 【色々試した結果】 ・panelをsplitContainer内に入れると上記したような動作は起きない。 ・他のpanel内に入れるだけではsplitContainerのように回避できない。 ・toolStripStatusLabel.Textを操作しなければ起きない。 ・文字列が変化しなければ同じ文字が代入されても起きない。 画像のフォームは、 左のpanel1とdataGridView1 : フォームに直接追加 右のpanel2とdataGridView2 : splitContainer内に追加 となっており、それぞれにSelectionChangedイベントが追加されています。起動後に適当にスクロールして適当にセルを選択した結果が画像となっています。 メソッドの内容は左側が int cc1 = 0; private void EVENT1(object s, EventArgs e) { // dataGridViewのセルに左上から // パネルのスクロール位置 + ", " を入力。 dataGridView1.Rows[cc1 / CC].Cells[cc1 % CC].Value = panel1.VerticalScroll.Value.ToString() + ", "; // 書き換え toolStripStatusLabel1.Text = panel1.VerticalScroll.Value.ToString(); // 最初に代入したdataGridViewのセルに // パネルのスクロール位置を追加 dataGridView1.Rows[cc1 / CC].Cells[cc1++ % CC].Value += panel1.VerticalScroll.Value.ToString(); } 右側のdataGridView.SelectionChangedに追加したメソッドは cc1, dataGridView1, panel1 の添字がすべて2になったものです。 CCはdataGridView.Columns.Countです。(図では CC = 4) 長くなりましたが、よろしくお願いします。

  • 子要素のスクロールが親要素に伝播しないようにしたい

    スクロールバーを持つ子要素 と その親要素であるwindow があり、 子要素のスクロール位置が一番上にある状態で、上に向かってホイールスクロールすると親要素windowのスクロールバーが動いてしまいます。 また、その逆に 子要素のスクロール位置が一番下にある状態で、下に向かってホイールスクロールすると親要素windowのスクロールバーが動いてしまいます。 この挙動をやめたいのですがどのようにすればよいでしょうか。 具体的にはFacebookの右上(外側のサイドバーの上)にあるフレンドのアクティビティを表示している領域の様な動作にしたいです。 下記コードでは実現出来ませんでした。 $("#sample").on('scroll mousewheel', function(event) { event.stopPropagation(); }); ライブラリはjqueryを使っています。 よろしくお願いします。

専門家に質問してみよう