c# - 无法删除最后剩余的项目 [英] c# - cannot delete last remaining item

查看:65
本文介绍了c# - 无法删除最后剩余的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个供个人使用的项目(简单的电话簿)。基本上,联系人显示在列表视图中并存储在XML文件中。我在列表视图(listView1)中删除最后剩余的项目时遇到问题。



这就是我的XML的样子:



I am working on a project (simple phone book) for personal use. Basically, the contacts are displayed in a listview and stored in a XML file. I am having trouble deleting the last remaining item in my listview (listView1).

This is how my XML looks like:

<People>
  <Person>
    <Name>John</Name>
    <Hometown>Washington</Hometown>
    <Address>231 Main Street</Address>
    <Birthday>130299511993682082</Birthday>
    <Phone>555-555-555</Phone>
    <Email>john@gmail.com</Email>
    <AdditionalInfo>Skype: john.123</AdditionalInfo>
  </Person>
  <Person>
    <Name>123</Name>
    <Hometown>
    </Hometown>
    <Address>
    </Address>
    <Birthday>130299621669230698</Birthday>
    <Phone>
    </Phone>
    <Email>
    </Email>
    <AdditionalInfo>
    </AdditionalInfo>
  </Person>
</People>





所以,让我们说我在列表中有5个联系人,当我尝试删除所有这些,这是不可能的。可以只删除其中的4个。当我尝试删除所有这些,然后关闭/运​​行应用程序时,将没有删除的联系人 - 所有这些仍将存在,就像我根本没有删除它们一样。当我尝试删除其中的4个并关闭/运行程序时,它们将被删除。当我尝试删除最后一个时,它也是不可能的 - 当我关闭/运行应用程序时,它将始终保持在那里。



此外,有时会出错当我尝试选择一些联系人时 - 通常是在删除它们之后。所以,为了清楚说明,让我说我有10个联系人并删除其中的5个,当我尝试选择第六个联系人时 - 错误显示:



IMAGE



我想也许这部分是代码被窃听:





So, let's say that I have got 5 contacts in the list and when I try to remove all of them, it's not possible. It is possible to remove only 4 of them. When I try to remove all of them and then close/run the application, there will be no removed contacts - all of them will still be there, like I haven't removed them at all. When I try to remove 4 of them and I close/run the program, they would be deleted. When I try to remove the last one, it is not possible either - when I close/run app it would always remain there.

Also, sometimes there is an error as well, when I try to just select some of the contacts - usually after already deleting them. So, just to make things clear, let's say that I have got 10 contacts and remove 5 of them, when I try to select the sixth contact - the error shows:

IMAGE

I think maybe this part of the code is bugged:

private void listView1_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0)
            {
                toolStripEdit.Enabled = false;
                RefreshAll();
                return;
            }
            Person person = new Person();
            person = FindPerson(listView1.SelectedItems[0].Text);
            txt_Name.Text = person.Name;
            txt_City.Text = person.Hometown;
            txt_Address.Text = person.Address;
            txt_Phone.Text = person.Phone;
            txt_Mail.Text = person.Email;
            txt_MoreInfo.Text = person.AdditionalInfo;
            dateTimePicker1.Value = person.Birthday;
            ReadOnlyON();
            toolStripEdit.Enabled = true;
            ExpandThis();
        }





以及这一个:





and this one as well:

void Rmv()
        {
            if (Properties.Settings.Default.Remove == true)
            {
                DialogResult dialogResult = MessageBox.Show("Are you sure you want to delete this contact?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialogResult == DialogResult.Yes)
                {
                    Remove();
                    if (Properties.Settings.Default.Sync == true) { Sync(); }
                }
                else if (dialogResult == DialogResult.No)
                {
                    return;
                }
            }
            else
            {
                Remove();
                if (Properties.Settings.Default.Sync == true) { Sync(); }
            }
        }
        void Remove()
        {
            Person person = new Person();
            person = FindPerson(listView1.SelectedItems[0].Text);
            if (listView1.SelectedItems.Count > 0)
            {
                try
                {
                    if (listView1.SelectedItems.Count == 0) return;
                    people.RemoveAt(listView1.SelectedItems[0].Index);
                    foreach (ListViewItem eachItem in listView1.SelectedItems)
                    {
                        listView1.Items.Remove(eachItem);
                    }
                }
                catch { }
                ClearAll();
                ReadOnlyON();
            }
            else
            {
                MessageBox.Show("Nothing is selected!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            ReadOnlyOFF();
            UserCount();
            if (Properties.Settings.Default.Sync == true) { Sync(); }
        }





由于在这里上传整个代码没有意义,我上传了它这里如果有人想帮忙并仔细看看它。



提前致谢。



如何解决这个问题?



@EDIT:



这是listview和XML之间的连接:





Since it doesn't makes sense to upload the whole code here, I have uploaded it here if someone wants to help and take a closer look at it.

Thanks in advance.

How can I solve this issue?

@

This is the connection between listview and XML:

private void Main_Load(object sender, EventArgs e)
        {
            LoadContacts();
        }

void LoadContacts()
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string phonebook_path = path + "\\Phonebook\\Contacts.xml";
            if (!File.Exists(phonebook_path))
            {
                XmlTextWriter xW = new XmlTextWriter(phonebook_path, Encoding.UTF8);
                xW.WriteStartElement("People");
                xW.WriteEndElement();
                xW.Close();
            }
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(phonebook_path);
            foreach (XmlNode xNode in xDoc.SelectNodes("People/Person"))
            {
                Person p = new Person();
                p.Name = xNode.SelectSingleNode("Name").InnerText;
                p.Hometown = xNode.SelectSingleNode("Hometown").InnerText;
                p.Address = xNode.SelectSingleNode("Address").InnerText;
                p.Birthday = DateTime.FromFileTime(Convert.ToInt64(xNode.SelectSingleNode("Birthday").InnerText));
                p.Phone = xNode.SelectSingleNode("Phone").InnerText;
                p.Email = xNode.SelectSingleNode("Email").InnerText;
                p.AdditionalInfo = xNode.SelectSingleNode("AdditionalInfo").InnerText;
                people.Add(p);
                listView1.Items.Add(p.Name);
                UserCount();
            }
        }




private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            XmlDocument xDoc = new XmlDocument();
            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string phonebook_path = path + "\\Phonebook\\Contacts.xml";
            xDoc.Load(phonebook_path);
            XmlNode xNode = xDoc.SelectSingleNode("People");
            xNode.RemoveAll();
            foreach (Person p in people)
            {
                XmlNode xTop = xDoc.CreateElement("Person");
                XmlNode xName = xDoc.CreateElement("Name");
                XmlNode xHometown = xDoc.CreateElement("Hometown");
                XmlNode xAddress = xDoc.CreateElement("Address");
                XmlNode xBirthday = xDoc.CreateElement("Birthday");
                XmlNode xPhone = xDoc.CreateElement("Phone");
                XmlNode xEmail = xDoc.CreateElement("Email");
                XmlNode xAdditionalInfo = xDoc.CreateElement("AdditionalInfo");
                xName.InnerText = p.Name;
                xHometown.InnerText = p.Hometown;
                xAddress.InnerText = p.Address;
                xBirthday.InnerText = p.Birthday.ToFileTime().ToString();
                xPhone.InnerText = p.Phone;
                xEmail.InnerText = p.Email;
                xAdditionalInfo.InnerText = p.AdditionalInfo;
                xTop.AppendChild(xName);
                xTop.AppendChild(xHometown);
                xTop.AppendChild(xAddress);
                xTop.AppendChild(xBirthday);
                xTop.AppendChild(xPhone);
                xTop.AppendChild(xEmail);
                xTop.AppendChild(xAdditionalInfo);
                xDoc.DocumentElement.AppendChild(xTop);
                xDoc.Save(phonebook_path);
            }
        }

推荐答案

我认为你是以错误的方式解决问题,试图混合UI,XML和数据。您需要分别处理这三个部分。首先,您不必直接处理XML。您可以使用负责此部分的数据合同。您只需拥有数据模型(一个或多个数据类),任何流中都会存储任意对象图,以便以后的方式进行恢复,并将所有引用放在合同下。请参阅:

http://msdn.microsoft.com/en-us /library/ms733127.aspx [ ^ ]。



有关详细信息,请参阅我过去的答案:

我如何在表单应用程序中使用XML文件编写器和阅读器? [ ^ ],

创建属性文件...... [ ^ ]。



另外,将UI分开。 UI部分应该是数据感知的,但数据模型不应该知道UI。 UI应该能够从数据模型中填充控件,UI中的更新应该刷新数据模型。序列化程序应仅适用于数据模型,并且与UI完全无关。



另请参阅:http://en.wikipedia.org/wiki/Separation_of_concerns [ ^ ]。



看起来你的场景很简单,所以我的简单考虑就足够了。为了更深入,您可以考虑学习我在过去的答案中提到的架构模式如何使用对话框控件中的值填充CList? [ ^ ]。



-SA
I think you are coming to the problem with a wrong side, trying to mix UI, XML and data. You need to deal with these three parts separately. First of all, you don't have to deal with XML directly. You can use Data Contract which takes care of this part. You simply have your data model (one or several data classes), and any arbitrary object graph will be stored for you in any stream to be later restored the way it was, with all its references put under the contract. Please see:
http://msdn.microsoft.com/en-us/library/ms733127.aspx[^].

For more detail, please see my past answers:
How can I utilize XML File streamwriter and reader in my form application?[^],
Creating property files...[^].

Also, separate the UI. The UI part should be data aware, but data model should not be aware of UI. UI should be able to populate control out of data model, and updates in UI should refresh the data model. The serializer should work only with data model and be totally agnostic to UI.

See also: http://en.wikipedia.org/wiki/Separation_of_concerns[^].

It looks like you scenario is simple enough, so the just my simple considerations could be enough. To go deeper, you can consider learning architectural patterns mentioned in my past answer: How to populate a CList with values from dialog controls?[^].

—SA


这是电话簿的修改代码。没有科幻小说。



Here's the modified code to the Phonebook. No science fiction included.

void Remove()
{
Person person = new Person();
try { person = FindPerson(listView1.SelectedItems[0].Text); } catch { return; }
if (listView1.SelectedItems.Count > 0)
{
try
{
if (listView1.SelectedItems.Count == 0) return;
foreach (ListViewItem eachItem in listView1.SelectedItems)
{
people.RemoveAll(x => x.Name == eachItem.Text);
listView1.Items[listView1.Items.Count - 1].Selected = true;
listView1.Items.Remove(eachItem);
}
}
catch { }
ClearAll();
ReadOnlyON();
}
else
{
MessageBox.Show("Nothing is selected!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
ReadOnlyOFF();
UserCount();
Sync();
}




private void listView1_SelectedIndexChanged(object sender, System.EventArgs e)
    {
if (listView1.SelectedItems.Count == 0)
{
toolStripEdit.Enabled = false;
RefreshAll();
return;
}

try {
Person person = new Person();
person = people[people.FindIndex(0, x => x.Name == listView1.SelectedItems[0].Text && x.Name != null)];
txt_Name.Text = person.Name;
txt_City.Text = person.Hometown;
txt_Address.Text = person.Address;
txt_Phone.Text = person.Phone;
txt_Mail.Text = person.Email;
txt_MoreInfo.Text = person.AdditionalInfo;
dateTimePicker1.Value = person.Birthday;
ReadOnlyON();
toolStripEdit.Enabled = true;
ExpandThis();
} catch (Exception ex) {
return;
}
}




private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
XmlDocument xDoc = new XmlDocument();
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string phonebook_path = path + "\\Phonebook\\Contacts.xml";
xDoc.Load(phonebook_path);
XmlNode xNode = xDoc.SelectSingleNode("People");
xNode.RemoveAll();
foreach (Person p in people)
{
XmlNode xTop = xDoc.CreateElement("Person");
XmlNode xName = xDoc.CreateElement("Name");
XmlNode xHometown = xDoc.CreateElement("Hometown");
XmlNode xAddress = xDoc.CreateElement("Address");
XmlNode xBirthday = xDoc.CreateElement("Birthday");
XmlNode xPhone = xDoc.CreateElement("Phone");
XmlNode xEmail = xDoc.CreateElement("Email");
XmlNode xAdditionalInfo = xDoc.CreateElement("AdditionalInfo");
xName.InnerText = p.Name;
xHometown.InnerText = p.Hometown;
xAddress.InnerText = p.Address;
xBirthday.InnerText = p.Birthday.ToFileTime().ToString();
xPhone.InnerText = p.Phone;
xEmail.InnerText = p.Email;
xAdditionalInfo.InnerText = p.AdditionalInfo;
xTop.AppendChild(xName);
xTop.AppendChild(xHometown);
xTop.AppendChild(xAddress);
xTop.AppendChild(xBirthday);
xTop.AppendChild(xPhone);
xTop.AppendChild(xEmail);
xTop.AppendChild(xAdditionalInfo);
xDoc.DocumentElement.AppendChild(xTop);
}

xDoc.Save(phonebook_path);
Sync();
SetStartup();
}





我还在我的添加方法中添加了此项,以确保没有双重联系人。





I also added this in my "Add" method to make sure there is no double contacts.

if (people.Find(x => x.Name == p.Name) == null) {  // I modifed this part
people.Add(p);
listView1.Items.Add(p.Name);
}
else {
MessageBox.Show("That contact already exists!");
}


要更直接地回答您的查询,一次删除单个项目时是否有效?此部分,您从通用列表中删除单个项目,然后从UI控件中删除一整套所选项目,似乎是一个问题:

To answer your query more directly, do things work when you remove a single item at a time? This part, where you remove a single item from your generic list and then a whole set of selected items from your UI control, appears to be a problem:
people.RemoveAt(listView1.SelectedItems[0].Index);
foreach (ListViewItem eachItem in listView1.SelectedItems)
{
    listView1.Items.Remove(eachItem);
}



看看这是否让你更接近功能:


See if this gets you closer to functional:

foreach (ListViewItem eachItem in listView1.SelectedItems)
{
    people.RemoveAt(eachItem.Index);
    listView1.Items.Remove(eachItem);
}


这篇关于c# - 无法删除最后剩余的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆