Порядок элементов управления в свойстве Control формы в C # - PullRequest
5 голосов
/ 11 ноября 2008

У меня есть особая проблема с порядком, в котором FlowLayoutPanels добавляются в свойство controls формы. Это то, что я пытался,

Я добавил 7 FlowLayoutPanels в окно приложения C # слева направо в виде вертикальных полос. Затем я пометил макеты потока как 1, 2, 3, ... 7 снова слева направо. Теперь в обработчике загрузки формы я написал следующий фрагмент:

    foreach (FlowLayoutPanel aDaysControl in this.Controls)
    {
        MessageBox.Show(aDaysControl.Tag.ToString());
    }

Я ожидал, что сообщения будут появляться в порядке 1, 2, ... 7 . Но я получил это в обратном порядке (7, 6, ... 1). Может ли кто-нибудь помочь мне с ошибкой, которую я совершил ??

Причина сохранения заказа

Я пытаюсь сделать элемент управления календаря с каждой строкой, представляющей день. Если месяц начинается со среды, тогда я необходимо добавить пустой ярлык первый (понедельник) и второй (вторник) строка. Таким образом, порядок имеет значение

Ответы [ 5 ]

7 голосов
/ 16 ноября 2011

Я знаю, что это довольно старый вопрос, но ...

Возможно, вы захотите использовать SetChildIndex. например this.Controls.SetChildIndex(button1, 0);

3 голосов
/ 11 ноября 2008

посмотрите порядок их добавления в форму в yourForm.designer.cs

1 голос
/ 29 августа 2012

Что если в будущем какой-то другой дизайнер уберет элементы управления, добавит обратно и т. Д.? Проверка дизайнера всегда беспорядок. Что было бы лучше, это отсортировать элементы управления в контейнере, прежде чем перечислять. Я использую этот метод расширения (если у вас есть Linq):

public static List<Control> ToControlsSorted(this Control panel)
{
    var controls = panel.Controls.OfType<Control>().ToList();
    controls.Sort((c1, c2) => c1.TabIndex.CompareTo(c2.TabIndex));
    return controls;
}

И вы можете:

foreach (FlowLayoutPanel aDaysControl in this.ToControlsSorted())
{
    MessageBox.Show(aDaysControl.TabIndex.ToString());
}

(выше для TabIndex). Было бы тривиально отсортировать в соответствии с Tag от этого.

1 голос
/ 11 ноября 2008

если вы посмотрите на код, сгенерированный конструктором Form1.designer.cs, он будет выглядеть примерно так:

        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(658, 160);
        this.Controls.Add(this.flowLayoutPanel7);
        this.Controls.Add(this.flowLayoutPanel6);
        this.Controls.Add(this.flowLayoutPanel5);
        this.Controls.Add(this.flowLayoutPanel4);
        this.Controls.Add(this.flowLayoutPanel3);
        this.Controls.Add(this.flowLayoutPanel2);
        this.Controls.Add(this.flowLayoutPanel1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

обратите внимание, как она была создана, сначала вы добавили панель 1, затем 2 и т. Д. но при прохождении кода сначала будет добавлено 7, а затем 6.

этот код будет в функции InitializeComponent (), сгенерированной конструктором.

Зачем они нужны для запуска в определенном порядке?

Я бы не стал полагаться на дизайнера в том порядке, в каком вы хотите .. Я бы сам отсортировал элементы управления:

        var flowpanelinOrder = from n in this.Controls.Cast<Control>()
                               where n is FlowLayoutPanel
                               orderby int.Parse(n.Tag.ToString())
                               select n;

        /* non linq
        List<Control> flowpanelinOrder = new List<Control>();
        foreach (Control c in this.Controls)
        {
            if (c is FlowLayoutPanel) flowpanelinOrder.Add(c);                
        }
        flowpanelinOrder.Sort();
         * */

        foreach (FlowLayoutPanel aDaysControl in flowpanelinOrder)
        {
            MessageBox.Show(aDaysControl.Tag.ToString());
        }
0 голосов
/ 11 ноября 2008

Это действительно проблема?

Пока пользовательский интерфейс работает правильно (например, с точки зрения порядка табуляции), я бы рекомендовал вам не делать никаких предположений относительно порядка, в котором они перечислены.

РЕДАКТИРОВАТЬ: Спасибо за объяснение вашего требования более подробно. Я думаю, что я все еще рекомендую не использовать порядок, который они хранят в коллекции элементов управления. Всегда лучше считать эти детали реализации «непрозрачными». У вас есть тег, связанный с каждым элементом управления, поэтому вы можете использовать его для определения правильного элемента управления. Чтобы ускорить обработку, вы можете создать массив из 7 элементов, который ссылается на элементы управления по порядковому номеру:

FlowLayoutPanel[] panels = new FlowLayoutPanel[7];

foreach(FlowLayoutPanel panel in this.Controls)
{
    panels[(int)panel.Tag] = panel;
}

// Now, you can reference the panels directly by subscript:

panels[2].BackColor = Color.Aquamarine;

Хотя я бы добавил некоторую проверку типов, чтобы сделать этот код немного более надежным!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...