Click here to Skip to main content
15,886,734 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello there, I created a program that is designed to add a bit of ease when it comes to change logs. Since I really didn't want anything over complicated that could've been a paid for app I decided to make my own. The only thing I have no idea to do is Serializing to save the current state of my custom class that has 6 lists that are for each type of change(Added, Removed, etc.) and one string used for keeping track of that version.

If a new version is created then the previous one(the whole class) gets added to a list of versions to add under the current version.

I intend to use the menuStrip control for handling the Opening/Saving of these different changes.
I'm just unsure how to handle serializing to make all the information available for storage.

I've read a few articles already about Serialization but I still remain quite confused and frustrated. All I know is you add "[Serializable]" to the beginning of the class and after that I get lost as I'm not sure how to handle the lists.

The two events that would trigger the "save" and "load" methods are click events that happen from the menuStrip.


On the main Form it just checks if the version has changed and if true adds the old version to a list which is another part I'm unsure of how to add to the "save" file.

C#
// pseudo-code-ish
private void btnChange_Click(object sender, EventArgs e)
{
    if(currentVersion is Old)
    {
        listOldVersion.Add(currentVersion);
    }
    currentVersion = new ChangeHandle(new version number);
}



ChangeHandle Class
C#
[Serializable]
public class ChangeHandle
{
    #region Fields

    private string sVersion;
    private List<string> listAdded;
    private List<string> listRemoved;
    private List<string> listBug;
    private List<string> listFixed;
    private List<string> listChanged;
    private List<string> listOther;

    #endregion

    #region Properties

    public string Version { get { return sVersion; } }

    #endregion

    #region Constructor

    public ChangeHandle(string Version)
    {
        sVersion = Version;
        listAdded = new List<string>();
        listRemoved = new List<string>();
        listBug = new List<string>();
        listFixed = new List<string>();
        listChanged = new List<string>();
        listOther = new List<string>();
    }

    #endregion

    #region Public Methods

    public void Added(string Change)
    {
        listAdded.Add(Change);
    }

    public void Removed(string Change)
    {
        listRemoved.Add(Change);
    }

    public void Bug(string Change)
    {
        listBug.Add(Change);
    }

    public void Fixed(string Change)
    {
        listFixed.Add(Change);
    }

    public void Changed(string Change)
    {
        listChanged.Add(Change);
    }

    public void Other(string Change)
    {
        listOther.Add(Change);
    }

    public StringBuilder Compile()
    {
        StringBuilder sbFinal = new StringBuilder();

        sbFinal.AppendLine();
        sbFinal.AppendLine(string.Format("Version: {0}",sVersion));

        foreach (string s in listAdded)
        {
            sbFinal.AppendLine(string.Format("  [Added]   - {0}", s));
        }
        foreach (string s in listRemoved)
        {
            sbFinal.AppendLine(string.Format("  [Removed] - {0}",s));
        }
        foreach (string s in listBug)
        {
            sbFinal.AppendLine(string.Format("  [Bug]     - {0}", s));
        }
        foreach (string s in listFixed)
        {
            sbFinal.AppendLine(string.Format("  [Fixed]   - {0}", s));
        }
        foreach (string s in listChanged)
        {
            sbFinal.AppendLine(string.Format("  [Changed] - {0}", s));
        }
        foreach (string s in listOther)
        {
            sbFinal.AppendLine(string.Format("  [Other]   - {0}", s));
        }

        return sbFinal;
    }

    #endregion
}



Any other information needed just let me know and I'll post back asap.

Thank you in advance!


<ArrayOfChangeHandle xmlns="http://schemas.datacontract.org/2004/07/DevLog" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ChangeHandle/><ChangeHandle/></ArrayOfChangeHandle>
Posted
Updated 18-Oct-13 0:42am
v2
Comments
BillWoodruff 17-Oct-13 22:28pm    
I don't see anything in the 'ChangeHandle Class that would be a problem to serialize, and serializing a List<ChangeHandle> should not be a problem, either.

currentVersion = new ChangeHandle(new version number); doesn't quite look right since the contstructor for ChangeHandle takes a string parameter.

You want to serialize both 'listOldVersions, and 'currentVersion ... correct ? Do you want to serialize them separately ... or ?

Also, do you know in what format you want to serialize in (binary ?, XML ?, JSON ?) ? Or, perhaps the format doesn't matter ? Serializing in XML or JSON would allow you to do complex things in the future (search, analysis, transformations) by just accessing the files, rather than deserializing all the files again.

Have you looked at, and tried, the examples of serialization and deserialization in the MSDN on-line docs ?
Jdlogic 17-Oct-13 23:21pm    
I had planned on doing it with xml because I could then read it and possibly debug it if I had problems deserializing it.

I think serializing them to the same file would work, I could create a method on the main form that put them both into one file(per 'Project').

What I'm trying to achieve out of this is once the file is loaded the current version is the same as it was when it was closed. I'll have a quick go at the examples again however I did grow frustrated with them...
BillWoodruff 18-Oct-13 1:51am    
It seems logical to me that you could add 'currentVersion to your list of versions, and then serialize that list. Then, when you de-serialized, just get the last element in the list, set the 'currentVersion equal to that, and then remove the last element in the list.

What do you think ?

1 solution

It would be the best to forget serialization based on Serializeable and migrate to Data Contracts:
http://msdn.microsoft.com/en-us/library/ms733127.aspx[^].

This is a really consistent approach, the easiest to use yet much more flexible. You don't need to implement anything special, take care about interfaces, access modifiers, inheritance. You implement data types in your own way, only add some attributes (which cannot effect anything beyond serialization).

Please see my past answers where I advocate this approach:
How can I utilize XML File streamwriter and reader in my form application?[^],
Creating property files...[^],
deseralize a json string array[^].

—SA
 
Share this answer
 
Comments
Jdlogic 18-Oct-13 6:20am    
Alright, seeing as how this seemed to be the best way I'm trying this approach first.

EDIT: I fixed the error below, yet I've ran into another problem. I opened the file and to my surprise it was more or less empty. I'm unsure of how I need to seperate the class infomation to have it save and load properly. This is what the file contains to hopefully better understand what I'm talking about(Please see the last bit of the OP to see the contents of the file, it doesn't want to show here).



Snippet of ChangeHandle class.
---------------
[DataContract()]
public class ChangeHandle : IExtensibleDataObject
{
---------------

List collection I'd like to serialize.
---------------
[DataMember()]
private List<changehandle> listChanges = new List<changehandle>();
---------------

StripMenu code:
---------------
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = "*.dlog";
ofd.ShowDialog();

FileStream fs = new FileStream(ofd.FileName, FileMode.Open);
ofd.Dispose();

XmlDictionaryReader xmlRead = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(List<changehandle>));

listChanges = (List<changehandle>)ser.ReadObject(xmlRead, true);
xmlRead.Close();
fs.Close();

listChanges.Remove(currentVersion);

CompilePreview();
}

private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
listChanges.Add(currentVersion);

DataContractSerializer der = new DataContractSerializer(typeof(List<changehandle>));
FileStream fs = new FileStream(string.Format("{0}.{1}", tbProject.Text, "dlog"), FileMode.Create);

der.WriteObject(fs, listChanges);
fs.Close();
}
---------------

Not too sure of what else to do. But thank you again for your help.
Sergey Alexandrovich Kryukov 18-Oct-13 9:47am    
So, what happened? Is it a list of strings or what? (There is no such thing as "new List()", is it an alias?)
Okay, did you fill in the list with data before storing? If a list element is not a string, what is that? If this is your type, you should also mark it with DataContract attribute.

(By the way, if you are going to support data files as some standard, deploy them, you should better add some unique namespace to DataContract attribute (better, some URL). It does not effect functionality but give uniqueness to the schema.)

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900