Laden...

Problem mit Autoscroll beim Panel und dynamische Controls

Letzter Beitrag vor 13 Jahren 4 Posts 1.428 Views
Problem mit Autoscroll beim Panel und dynamische Controls

Hi,

ich habe ein Panel dass ich dynamisch mit Labels fülle.
Um zu scrollen ist beim Panel der Autoscroll aktiv.

Problem:
Sobald ich 2 Labels durch Clicken vertausche und die Autoscrollposition !=0 ist,
verschieben sich alle Controls ?um die Scrollposition? nach unten.

(Ich brauche eine 1 spaltige Auflistung an Steuerelementen.
Der Benutzer soll Steuerelemente hinzufügen, verschieben und löschen können.
Mehr als 100 Einträge in der Liste werden es nicht werden.)

Was mache ich falsch?
Bin für jeden Ratschlag dankbar!

Gruß,
CoLo


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //Panel und Labels hinzufügen
            {
                //Panel
                Panel panel1 = new Panel();
                {
                    panel1.Name = "panel1";
                    panel1.BackColor = Color.Silver;
                    panel1.AutoScroll = true;
                    panel1.Location = new Point(10, 10);
                    panel1.Size = new Size(this.ClientSize.Width - 20, this.ClientSize.Height - 20);
                    panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
                    this.Controls.Add(panel1);
                }

                //Labels
                for (int i = 0; i < 30; i++)
                {
                    Label lbl = new Label();
                    lbl.Name = "Label" + i;
                    lbl.Text = lbl.Name;
                    lbl.Click += new EventHandler(lbl_Click);
                    m_items.Add(lbl);
                    panel1.Controls.Add(lbl);
                }
                ItemsUpdatePositions();
            }
        }

        List<Control> m_items = new List<Control>();
        void ItemsUpdatePositions()
        {
            int top = 0;
            for (int i = 0; i < m_items.Count; i++)
            {
                m_items[i].Location = new Point(0, top);
                top += m_items[i].Height;
            }
        }
        bool ItemsSwap(int x, int y)
        {
            int max = m_items.Count - 1;
            if (!((0 <= x) && (x <= max))) return false;
            if (!((0 <= y) && (y <= max))) return false;

            Control itemX = m_items[x];
            m_items[x] = m_items[y];
            m_items[y] = itemX;
            return true;
        }

        //Vertausche beim Click 2 Labels (hier passiert's)
        void lbl_Click(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            lbl.BackColor = Color.Yellow;
            int i = m_items.IndexOf(lbl);
            
            if (ItemsSwap(i, i + 1))
            {
                ItemsUpdatePositions();
            }
        }
    }

Platziere ein Panel mit AutoSize=true in dein AutoScroll Panel und deine Labels platzierst du in dem inneren Panel.

lg XXX

//EDIT: Zusätzlich könntest du anstatt des manuellen Platzierens mit einem FlowLayoutPanel oder alternativ mit Dock=Top arbeiten.

Danke xxxprod, das ist genial! 😁


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //Panels und Labels hinzufügen
            {
                //Panels
                Panel pnlOuter = new Panel();
                {
                    pnlOuter.Name = "pnlOuter";
                    pnlOuter.BackColor = Color.Silver;
                    pnlOuter.AutoScroll = true;
                    pnlOuter.Dock = DockStyle.Fill;
                    this.Controls.Add(pnlOuter);
                }
                Panel pnlInner = new Panel();
                {
                    pnlInner.Name = "pnlInner";
                    pnlInner.BackColor = Color.WhiteSmoke;
                    pnlInner.AutoSize = true;
                    pnlInner.Dock = DockStyle.Top;
                    pnlOuter.Controls.Add(pnlInner);                    
                }

                //Labels
                for (int i = 0; i < 30; i++)
                {
                    Label lbl = new Label();
                    lbl.Name = "Label" + i;
                    lbl.Text = lbl.Name;
                    lbl.Click += new EventHandler(lbl_Click);
                    m_items.Add(lbl);                    
                    pnlInner.Controls.Add(lbl);
                }
                ItemsUpdatePositions();
            }
        }

        List<Control> m_items = new List<Control>();
        void ItemsUpdatePositions()
        {
            int top = 0;
            for (int i = 0; i < m_items.Count; i++)
            {
                m_items[i].Location = new Point(0, top);
                top += m_items[i].Height;
            }
        }
        bool ItemsSwap(int x, int y)
        {
            int max = m_items.Count - 1;
            if (!((0 <= x) && (x <= max))) return false;
            if (!((0 <= y) && (y <= max))) return false;

            Control itemX = m_items[x];
            m_items[x] = m_items[y];
            m_items[y] = itemX;
            return true;
        }


        void lbl_Click(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            lbl.BackColor = Color.Yellow;
            int i = m_items.IndexOf(lbl);
            if (ItemsSwap(i, i + 1))
            {
                ItemsUpdatePositions();
            }
        }
    }

Wenn man am Layout von Controls herumfummelt (insbes. sone Tausch-Aktion), da sollte man ScrollPanel.SuspendLayout/ResumeLayout() aufrufen, und sollte eiglich Ruhe sein.

Der frühe Apfel fängt den Wurm.