Проблема с обновлением элемента управления ListBox в WPF - PullRequest
0 голосов
/ 09 октября 2010

У меня есть приложение, которое должно контролировать 211 стержней, и каждые 5 секунд оно будет обновлять 2 элемента управления ListBox, каждый из которых содержит либо вставленные стержни, либо удаленные. Когда я вручную использую кнопку для вставки / удаления стержней, код выполняется отлично, и ListBoxes обновляется должным образом. Когда я использую глобальную кнопку, которая вставляет все 211, один из элементов управления ListBox перестает работать правильно.

Код для обновления ListBox

bool IClear = true, RClear = true;
        for (int foo = 0; foo < Rods.Count; foo++)
        {
            if (Rods[foo].State == RodState.Inserted)
            {
                UpdateRodList update = new UpdateRodList(UpdateIRodUI);
                if (IClear)
                {
                    InsertedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, true);
                    IClear = false;
                }
                else
                {
                    InsertedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, false);
                }
            }
            if (Rods[foo].State == RodState.Removed)
            {
                UpdateRodList update = new UpdateRodList(UpdateRRodUI);
                if (RClear)
                {
                    RemovedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, true);
                    RClear = false;
                }
                else
                {
                    RemovedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, false);
                }
            }
        }

Код для кнопки вставки (кнопка удаления аналогична)

Int32[] RodsID = null;
        bool bParsed = false;
        if (RemovingRods_.Text.Contains("*"))
        {
            RodsID = new Int32[211];
            for (int i = 0; i < 211; i++)
            {
                RodsID[i] = i;
            }
            RemovingRods_.Text = "";
            bParsed = true;
        }
        if (RemovingRods_.Text.Contains("-"))
        {
            string stext = RemovingRods_.Text;
            Int32 a = Int32.Parse(RemovingRods_.Text.Substring(0, RemovingRods_.Text.IndexOf("-")));
            Int32 b = Int32.Parse(RemovingRods_.Text.Substring(RemovingRods_.Text.IndexOf("-") + 1));
            RodsID = new Int32[b - a];
            for (int i = 0; i < b - a; i++)
            {
                RodsID[i] = i + a;
            }
            RemovingRods_.Text = "";
            bParsed = true;
        }
        if (!bParsed)
        {
            string[] RodsID_;
            char[] split = { ' ' };
            RodsID_ = RemovingRods_.Text.Split(split);
            RemovingRods_.Text = "";
            RodsID = new Int32[RodsID_.Length];
            for (int i = 0; i < RodsID_.Length; i++)
            {
                RodsID[i] = Int32.Parse(RodsID_[i]);
            }
        }
        foreach (int numb in RodsID)
        {
            if (Rods[numb].Type == "Control Rod")
            {
                ControlRod Rod = new ControlRod();
                Rod.Number = numb;
                Rod.RodState = RodState.Changing;
                RemovingCRods.Add(Rod);
            }
            if (Rods[numb].Type == "Shortened Control Rod")
            {
                ShortenedControlRod Rod = new ShortenedControlRod();
                Rod.Number = numb;
                Rod.RodState = RodState.Changing;
                RemovingSRods.Add(Rod);
            }
            if (Rods[numb].Type == "Automated Control Rod")
            {
                // Automated Rods -- NO MANUAL CONTROL
            }
        }

И код глобальной кнопки

try
        {
            Int32[] RodsID = null;
            string text = "0-211";
            RodsID = new Int32[211];
            for (int i = 0; i < 211; i++)
            {
                RodsID[i] = i;
            }
            foreach (int numb in RodsID)
            {
                if (Rods[numb].Type == "Control Rod")
                {
                    ControlRod Rod = new ControlRod();
                    Rod.Number = numb;
                    Rod.RodState = RodState.Changing;
                    InsertingCRods.Add(Rod);
                }
                if (Rods[numb].Type == "Shortened Control Rod")
                {
                    ShortenedControlRod Rod = new ShortenedControlRod();
                    Rod.Number = numb;
                    Rod.RodState = RodState.Changing;
                    InsertingSRods.Add(Rod);
                }
                if (Rods[numb].Type == "Automated Control Rod")
                {
                    AutomatedControlRod Rod = new AutomatedControlRod();
                    Rod.Number = numb;
                    Rod.RodState = RodState.Changing;
                    InsertingARods.Add(Rod);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

Что происходит, когда я нажимаю глобальный, список удаленных стержней будет иметь все стержни, как и должно быть, а список вставленных стержней будет содержать стержни, которые были вставлены до того, как я нажал кнопку. Это как если бы я нажал эту кнопку, этот элемент управления не обновляется. Постскриптум Если я удаляю стержни вручную, используя кнопку или вставляю, это прекрасно работает.

Что касается кода, запрошенного Марко:

 private void UpdateIRodUI(Int32 foo, Boolean clear)
    {
        if (clear)
        {
            InsertedRods.Items.Clear();
        }
        InsertedRods.Items.Add(Rods[foo].Number + " : " + Rods[foo].Type + " (" + foo.ToString() + ")");
    }

    private void UpdateRRodUI(Int32 foo, Boolean clear)
    {
        if (clear)
        {
            RemovedRods.Items.Clear();
        }
        RemovedRods.Items.Add(Rods[foo].Number + " : " + Rods[foo].Type + " (" + foo.ToString() + ")");
    }

Обновление: я поместил обновленный код ListBox в отдельную функцию и принял совет Марко, а также вставил функцию InsertRods. Теперь все работает нормально, но кажется, что после того, как я нажимаю кнопку «чрезвычайной ситуации», ListBox InsertedRods обновляется и работает просто отлично, но RemovedRods просто перестает обновляться, если я не делаю это вручную (он должен обновляться каждые 5 секунд через событие Tick). Я даже попытался вставить все стержни, обновить ListBox и очистить «неисправный» ListBox и все еще ничего, тот же результат.

1 Ответ

1 голос
/ 09 октября 2010

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

1) Вы разместили свой код для обновления ListBox, но из другого неяснодве части кода, которые вы называете методом обновления ListBox?

2) Код, который вы разместили для «кнопки вставки», больше похож на код из «кнопки удаления» из-за Removing_Rods.Add ()... Но почему вы дублируете свой код кнопки вставки / удаления в глобальном коде кнопки?Почему бы не иметь метод вставки, который вызывается как кнопкой вставки, так и глобальной (вставкой) кнопкой?И то же самое для удаления.Если вам нужно немного изменить код в зависимости от того, является ли вызывающая кнопка кнопкой вставки или глобальной кнопкой, вы можете передать переменную и проверить ее в методе вставки.

3) Вы пытались отладить код?Как в том, вызывается ли метод обновления списка при выполнении кода глобальной кнопки ...

...