none
Баг Windows Forms или это как-то объясняется? Удаляется не та вкладка в TabControl. RRS feed

  • Вопрос

  • Можете скопировать себе этот код в пустой Windows Forms проект и увидеть баг в действии
     
    using System;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace WinForms_TabPage_RemoveAt
    {
     public partial class Form1 : Form
     {
      const int time = 2000;
      TabControl tabControl;
    
      public Form1()
      {
       InitializeComponent();
       tabControl = new TabControl();
    
       StartPosition = FormStartPosition.CenterScreen;
       Width = 800;
       Height = 480;
       MinimumSize = new System.Drawing.Size(Width, Height);
       tabControl.Width = Width - 90;
       tabControl.Left = 2;
       tabControl.Height = Height - 50;
    
       Button btnRemoveTabPage = new Button();
       btnRemoveTabPage.Width = 65;
       btnRemoveTabPage.Height = 23;
       btnRemoveTabPage.Top = 30;
       btnRemoveTabPage.Left = Width - btnRemoveTabPage.Width - 20;
       btnRemoveTabPage.Anchor = AnchorStyles.Right;
       btnRemoveTabPage.Text = "Нажми";
    
       Controls.Add(tabControl);
       Controls.Add(btnRemoveTabPage);
    
       tabControl.TabPages.Add("TabPage 1");
       tabControl.TabPages.Add("TabPage 2");
       tabControl.TabPages.Add("TabPage 3");
       tabControl.TabPages.Add("TabPage 4");
    
       UpdateNamesForPages();
       tabControl.SelectedIndexChanged += new EventHandler(tabControl1_SelectedIndexChanged);
    
       btnRemoveTabPage.Click +=new EventHandler(btnRemoveTabPage_Click);
      }
    
      void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
      {
       Text = ((TabControl)sender).SelectedIndex.ToString();
      }
    
      private void btnRemoveTabPage_Click(object sender, EventArgs e)
      {
       tabControl.SelectTab(3);
       UpdateNamesForPages();
       tabControl.Update();
    
       Thread.Sleep(time);
    
    
       tabControl.TabPages.RemoveAt(2);
       tabControl1_SelectedIndexChanged(tabControl, new EventArgs());
       UpdateNamesForPages();
       tabControl.Update();
    
       Thread.Sleep(time);
    
    
       tabControl.TabPages.Insert(2, "tabPage**");
       tabControl1_SelectedIndexChanged(tabControl, new EventArgs());
       UpdateNamesForPages();
       tabControl.Update();
    
       Thread.Sleep(time);
    
    
       tabControl.SelectTab(2);
       UpdateNamesForPages();
       tabControl.Update();
    
       Thread.Sleep(time);
    
    
       tabControl.SelectTab(3);
       UpdateNamesForPages();
       tabControl.Update();
    
    
       Thread.Sleep(time);
    
       tabControl.TabPages.RemoveAt(2);
       tabControl1_SelectedIndexChanged(tabControl, new EventArgs());
       UpdateNamesForPages();
       tabControl.Update();
    
      }
    
      private void UpdateNamesForPages()
      {
       for (int i = 0; i < tabControl.TabPages.Count; i++)
       {
        TabPage tab = tabControl.TabPages[i];
        String originalName = tab.Text.Substring(0, 9);
        tab.Text = String.Format("{0} индекс - {1}", originalName, i);
       }
      }
     }
    }
    
    
     
    Фишка в последнем удалении вкладки, удаляется вкладка не под тем индексом.




    • Изменено Casper-SC 7 мая 2011 г. 15:21 Походу всерьёз никто не воспринимает, а баг реален. Я тоже всерьёз не воспринимал.

Ответы

  • Это форум. и завтра послезавтра - вам его точно не поправят :).

    баги постить сюда: https://connect.microsoft.com/

    процедура есть здесь: http://social.msdn.microsoft.com/Forums/en/xmlandnetfx/thread/6bc244ba-8549-42e9-954f-37ec793e76f5

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа Abolmasov Dmitry 13 мая 2011 г. 9:26
  • Да, это баг. Удаление также неправильно работает, при удалении по ключу RemoveByKey. Создайте багрепорт на Connect и не забудьте написать здесь ссылку на баг, чтобы пользователи могли проголосовать за него. Спасибо.

    Можно использовать функцию Remove в которую передавать либо созданный ранее таб, который необходимо удалить (tabPage2 из примера Владимир В), либо написать свою обертку над этой функцией, которая принимает индекс и удаляет таб по индексу:

      public static class TabControlHelper
      {
        public static void RemoveAtIndex(this TabControl.TabPageCollection pages,int index)
        {
          pages.Remove(pages[index]);
        }
      }
    
    //...
    
      tabControl.TabPages.RemoveAtIndex(2);
    

     


    Для связи [mail]
    • Помечено в качестве ответа Abolmasov Dmitry 13 мая 2011 г. 9:26

Все ответы

  • Вы правы, так и есть. Тот же баг если попытаться удалить RemoveAt(1) - только наоборот. Думаю именно диначмическое добавление-удаление "смущает" поведение контрола. 

    Но баг таки есть, безусловно.

    И проблема не в том, что кто-то воспринимает это или нет всерьез, больше это вопрос времени, что нужно запустить отдельный проект чтобы это проверить.


    Don't forget to mark the correct answer Blog
  • Так я не просто так сюда код выложил. Мне интересно в майкрософте этот поправят или так и останется без внимания? Можно сказать сделал доброе дело, а ответа не слышал =)
  • Это форум. и завтра послезавтра - вам его точно не поправят :).

    баги постить сюда: https://connect.microsoft.com/

    процедура есть здесь: http://social.msdn.microsoft.com/Forums/en/xmlandnetfx/thread/6bc244ba-8549-42e9-954f-37ec793e76f5

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа Abolmasov Dmitry 13 мая 2011 г. 9:26
  • Возможно, что мой пример с той же ошибкой выглядит еще короче :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;

    namespace TabPageHide
    {
        public partial class Form1 : Form
        {
            TabControl tabControl;
            TabPage tabPage0;
            TabPage tabPage1;
            TabPage tabPage2;
            TabPage tabPage3;
            Button buttonStart;

            public Form1()
            {
                InitializeComponent();

                tabControl = new System.Windows.Forms.TabControl();
                tabControl.Location = new System.Drawing.Point(10, 10);
                tabControl.Size = new System.Drawing.Size(200, 140);
                tabControl.Name = "tabControl";

                tabPage0 = new System.Windows.Forms.TabPage();
                tabPage0.Name = "tabPage0";
                tabPage0.Text = "Page 0";

                tabPage1 = new System.Windows.Forms.TabPage();
                tabPage1.Name = "tabPage1";
                tabPage1.Text = "Page 1";

                tabPage2 = new System.Windows.Forms.TabPage();
                tabPage2.Name = "tabPage2";
                tabPage2.Text = "Page 2";

                tabPage3 = new System.Windows.Forms.TabPage();
                tabPage3.Name = "tabPage3";
                tabPage3.Text = "Page 3";

                tabControl.Controls.Add(tabPage0);
                tabControl.Controls.Add(tabPage1);
                tabControl.Controls.Add(tabPage2);
                tabControl.Controls.Add(tabPage3);

                buttonStart = new System.Windows.Forms.Button();
                buttonStart.Location = new System.Drawing.Point(10, 160);
                buttonStart.Size = new System.Drawing.Size(170, 30);
                buttonStart.Name = "buttonStart";
                buttonStart.Text = "Start Test";
                buttonStart.Click += new System.EventHandler(this.buttonStart_Click);

                Controls.Add(buttonStart);
                Controls.Add(tabControl);
            }

            private void buttonStart_Click(object sender, EventArgs e)
            {
                tabControl.SelectTab(3);
                tabControl.Update();
                Thread.Sleep(2000);

                tabControl.TabPages.RemoveAt(2);
                tabControl.Update();
                Thread.Sleep(2000);

                tabControl.TabPages.Insert(2, tabPage2);
                tabControl.Update();
                Thread.Sleep(2000);

                tabControl.SelectTab(2);
                tabControl.Update();
                Thread.Sleep(2000);

                tabControl.SelectTab(3);
                tabControl.Update();
                Thread.Sleep(2000);

                tabControl.TabPages.RemoveAt(2); // удаляется не та страница !
                tabControl.Update();
            }
        }
    }

  • Да, это баг. Удаление также неправильно работает, при удалении по ключу RemoveByKey. Создайте багрепорт на Connect и не забудьте написать здесь ссылку на баг, чтобы пользователи могли проголосовать за него. Спасибо.

    Можно использовать функцию Remove в которую передавать либо созданный ранее таб, который необходимо удалить (tabPage2 из примера Владимир В), либо написать свою обертку над этой функцией, которая принимает индекс и удаляет таб по индексу:

      public static class TabControlHelper
      {
        public static void RemoveAtIndex(this TabControl.TabPageCollection pages,int index)
        {
          pages.Remove(pages[index]);
        }
      }
    
    //...
    
      tabControl.TabPages.RemoveAtIndex(2);
    

     


    Для связи [mail]
    • Помечено в качестве ответа Abolmasov Dmitry 13 мая 2011 г. 9:26