Question

I'm trying to save the contents of my listView. But I'm having some issues with it. In my text file it will look like this:

ListViewItem: {1234};ListViewSubItem: {daily};ListViewSubItem: {Backup};ListViewSubItem: {Every 2 days at: 23:0};ListViewSubItem: {};ListViewSubItem: {}

But I don't like that it adds "ListViewItem:" and "ListViewSubItem:" etc with my data.. I just want those strings inside {}.

And here is my code:

        FileStream file = new FileStream(dataFolder + "\\BukkitGUI\\schedule.txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter sw = new StreamWriter(file);

        foreach (ListViewItem listItem in listView1.Items)
        {
            sw.WriteLine(listItem + ";" + listItem.SubItems[1] + ";" + listItem.SubItems[2] + ";" + listItem.SubItems[3] + ";" + listItem.SubItems[4] + ";" + listItem.SubItems[5]);
        }

        sw.Close();
        file.Close();

Any help on this?

EDIT: Image of my listView: enter image description here

Was it helpful?

Solution

Your code does this:

foreach (ListViewItem listItem in listView1.Items)
{
    sw.WriteLine(listItem + ";" + listItem.SubItems[1] + ";" + listItem.SubItems[2] + ";" + listItem.SubItems[3] + ";" + listItem.SubItems[4] + ";" + listItem.SubItems[5]);
}

This is doing the following:

foreach (ListViewItem listItem in listView1.Items)
{
    string listItemString = listItem.ToString();
    // etc.
}

What do you think the value of listItem.ToString() will be?

The default implementation of object.ToString() simply outputs the name of the type. The implementation for ListViewItem and ListViewSubItem apparently output the name of the type, plus the content of the item or subitem.

If you want something different output, then you need to do it yourself. Output listItem.Text and listItem.SubItems[n].Text instead.

OTHER TIPS

Q: If your input data is in JSON format, perhaps your best bet is to get a JSON parser?

For example:

Otherwise, if it's just a "funny format", look at the .Net TextFieldParser:

It's too long to post it as comment so I'll write an answer. I hope at least it will give you a good direction on one way to deal with it. In general you need some way to manipulate string. Many options comes to mind, but in your case I think that using regex or regular expressions is the best option since they are powerful, you have a clear criteria about what should go inside the .txt file and what not, and you work with relatively small amount of data so even though the regular expressions are considered slower than other options, in your case I think this won't be a problem.

Here is what I've tried - just created a static method (some sort of helper method) that will clean the string for you so that you get only the info you need. The method itself is :

    public static string ParseListView(string ListViewText)
    {
        var regex = new System.Text.RegularExpressions.Regex("{.*?}");
        var match = regex.Match(ListViewText);

        return match.ToString().TrimStart('{').TrimEnd('}');
    }

Pretty simple method. There's a lot of things that you can adjust if needed to work better for your case. For example I'm using regex.Match() which returns only the first match, but maybe you'll find regex.Matches() more suitable for you. There are also a lot of other options when you work with regular expressions in C# so be sure to check them out.

Then in you foreach loop you just:

foreach (ListViewItem listItem in listView1.Items)
        {
            sw.WriteLine(ParseListView(listItem) + ";" + ParseListView(listItem.SubItems[1]) + ";" + ParseListView(listItem.SubItems[2]) + ";" + ParseListView(listItem.SubItems[3]) + ";" + ParseListView(listItem.SubItems[4]) + ";" + ParseListView(listItem.SubItems[5]));
        }

Of course this looks pretty ugly so the logic inside the foreach loop most probably can be improved but I think this will get you going.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top