Функция не исключает, как ожидалось - PullRequest
1 голос
/ 18 марта 2012

У меня есть функция, InsertItems:

    public void InsertItems()
    {
        todoitemList.Clear();
        todoSelect.Items.Clear();

        foreach (XmlNode xmlNode in xmlDoc.SelectNodes("ToDoList/ToDo"))
        {
            ToDoItem item = new ToDoItem();

            item.ID = xmlNode.SelectSingleNode("ID").InnerText;
            item.Title = xmlNode.SelectSingleNode("Title").InnerText;
            item.Description = xmlNode.SelectSingleNode("Desc").InnerText;
            item.PriorityLevel = xmlNode.SelectSingleNode("Priority").InnerText;
            item.Date = Convert.ToDateTime(xmlNode.SelectSingleNode("Date").InnerText);
            item.TimeHour = Convert.ToInt32(xmlNode.SelectSingleNode("TimeHour").InnerText);
            item.TimeMinute = Convert.ToInt32(xmlNode.SelectSingleNode("TimeMinute").InnerText);
            item.TimeSecond = Convert.ToInt32(xmlNode.SelectSingleNode("TimeSecond").InnerText);
            item.Completed = xmlNode.SelectSingleNode("Completed").InnerText;

            todoitemList.Add(item);
            todoSelect.Items.Add(item.Title);
            todoIDList.Add(item.ID);
        }
    }

Эта функция очищает как список, так и поле со списком, в которое используется для выбора элементов, а затем заполняет список соответствующими данными. ToDoItem - это класс, который содержит свойства - ID, заголовок и т. Д.

Когда функция выполняется в Form1.cs, она полностью работает, как и ожидалось, очищает список и добавляет новые данные. Однако, когда функция выполняется внутри Form2.cs (main.InsertItems ()), цикл foreach, кажется, никогда не запускается, и я действительно не знаю, что вызывает это.

Любая помощь очень ценится!

-

Edit:

main.InsertItems () вызывается в следующей функции:

    private void createNew_Click(object sender, EventArgs e)
    {
        if (CheckAll())
        {
            XmlNode xmlNode = xmlDoc.CreateNode(XmlNodeType.Element, "ToDo", null);

            XmlNode xmlNodeID = xmlDoc.CreateElement("ID");
            xmlNodeID.InnerText = CreateRandomID();

            XmlNode xmlNodeTitle = xmlDoc.CreateElement("Title");
            xmlNodeTitle.InnerText = textBoxTitle.Text;

            XmlNode xmlNodeDesc = xmlDoc.CreateElement("Desc");
            xmlNodeDesc.InnerText = textBoxDesc.Text;

            XmlNode xmlNodePriority = xmlDoc.CreateElement("Priority");
            xmlNodePriority.InnerText = Convert.ToString(priorityLevel.SelectedItem);

            XmlNode xmlNodeDate = xmlDoc.CreateElement("Date");
            string currentDate = Convert.ToString(monthCalendar.SelectionRange.Start);
            string strippedDate = currentDate.Substring(0, currentDate.Length - 8);
            strippedDate += timeHour.Text + ":" + timeMinute.Text + ":" + timeSecond.Text;
            xmlNodeDate.InnerText = strippedDate;

            XmlNode xmlNodeTimeHour = xmlDoc.CreateElement("TimeHour");
            xmlNodeTimeHour.InnerText = timeHour.Text;

            XmlNode xmlNodeTimeMinute = xmlDoc.CreateElement("TimeMinute");
            xmlNodeTimeMinute.InnerText = timeMinute.Text;

            XmlNode xmlNodeTimeSecond = xmlDoc.CreateElement("TimeSecond");
            xmlNodeTimeSecond.InnerText = timeSecond.Text;

            XmlNode xmlNodeCompleted = xmlDoc.CreateElement("Completed");
            xmlNodeCompleted.InnerText = "False";

            xmlNode.AppendChild(xmlNodeID);
            xmlNode.AppendChild(xmlNodeTitle);
            xmlNode.AppendChild(xmlNodeDesc);
            xmlNode.AppendChild(xmlNodePriority);
            xmlNode.AppendChild(xmlNodeDate);
            xmlNode.AppendChild(xmlNodeTimeHour);
            xmlNode.AppendChild(xmlNodeTimeMinute);
            xmlNode.AppendChild(xmlNodeTimeSecond);
            xmlNode.AppendChild(xmlNodeCompleted);

            xmlDoc.DocumentElement.AppendChild(xmlNode);

            try
            {
                xmlDoc.Save(_fileName);
                MessageBox.Show("Item successfully added!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                main.InsertItems();
            }
            catch (XmlException)
            {
                MessageBox.Show("Error! The item could not be added due to an XML error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (IOException)
            {
                MessageBox.Show("Error! The file could not be found or written to. Item could not be added.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception)
            {
                MessageBox.Show("Error! An unknown error occured. Item could not be added.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.Close();
        }
    }

CheckAll возвращает логическое значение -> true, если все поля действительны.

Переменная _fileName правильная и сохраняется в правильный файл.

Ответы [ 2 ]

2 голосов
/ 18 марта 2012

Проблема в том, что вы не перезагружаете xmlDoc в Form1.InsertItems.

В коде, который вы разместили, перед вызовом Form1.InsertItems из Form2 вы записываете файл на диск, но поскольку вы не передаете ссылку на обновленный xmlDoc с Form2 на Form1 , вы не видите изменений, показанных на Form1. InsertItems работает, как и ожидалось, когда вы вызываете его из Form1, потому что xmlDoc является переменной-членом для Form1, поэтому изменения доступны в InsertItems при вызове из Form1.

Попробуйте либо перезагрузить XmlDocument из файловой системы в начале InsertItems, либо передать XmlDocument в InsertItems в качестве параметра.

0 голосов
/ 18 марта 2012

Другой класс работает в другом потоке? Это может произойти из-за исключения между потоками. По сути, существует только один поток пользовательского интерфейса для обновления элементов пользовательского интерфейса. Если вы попытаетесь обновить элементы пользовательского интерфейса из другого потока, вы получите исключение. Возможно, вы просто проглотили эту ошибку. Вы можете попробовать отладить его, и вы увидите исключение до того, как оно будет съедено. Если это действительно так, то для выполнения обновления вам нужно будет снова вызвать поток пользовательского интерфейса.

Вот хорошая статья об обновлениях пользовательского интерфейса для кросс-потоков winforms.

Вот примерный пример того, как будет выглядеть ваш код (он не проверяется компилятором, но должен быть закрыт:))

if ( main.InvokeRequired ) {
    main.Invoke(new MethodInvoker(main.InsertItems));
} else {
    main.InsertItems();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...