What I want to do is have my form save and load the 27 fields I have, but I want to close the program and it save and load to a file but I dont know how to have it write or read from a file. Please help me. :wave: :wave: :wave:
Printable View
What I want to do is have my form save and load the 27 fields I have, but I want to close the program and it save and load to a file but I dont know how to have it write or read from a file. Please help me. :wave: :wave: :wave:
do you know anything about streamreaders and writers?
No I don't
this is what my form looks like
wow thats a cool form :cool:
here's a sample on how to read and write a txt fileQuote:
Originally Posted by Kesk
VB Code:
Imports System.IO Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim s As New StreamWriter("f:/test1.txt") Dim o As String For Each o In ListBox1.Items s.WriteLine(o) Next MessageBox.Show("file has been successfully saved") s.Close() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim s As New StreamReader("f:/test1.txt") s.BaseStream.Seek(0, SeekOrigin.Begin) While s.Peek > -1 ListBox2.Items.Add(s.ReadLine) End While s.Close() End Sub
So does that save all the fields information then?? I have a few more I added fields to save, so would I have to add more code??
thanks techwizz
There is nothing wrong with mar_zim's suggestion, but I think it would be easier overall to create a class to hold all your values in properties and then serialize an instance of your class to and from an XML file.
I agree. Classes all the way. A class would be a perfect way to do this, because it centralizes all the data in one object that you can pass back and forth in one line of code :DQuote:
Originally Posted by jmcilhinney
so how would i do that, I have only been programmin for a few months
See this thread for an example of how I accomplish this task. Some others may have slightly different ideas but this method always works for me.
but i want to save to one file and load from it
The method I suggested does save to one file. You create a class that stores all the values you want to save. I always use the preferred practice of storing each value in a private variable and exposing it through a public property. You then serialize the entires object to an XML file, which takes four lines of code. To load your data, you deserialize your XML file to an object, which also takes four lines of code. There are various advantages to this method. Because the serialization/deserialization mechanism is built into the .NET Framework, you only need those four lines of code regardless of how many values you want to save and what type they are. They can even be complex objects themselves, not just integers and strings. Also, because you have all your values contained in a single object, you can easily pass them around your app as a single entity.
how would i change that to take advantage of mine??
I will create an abbreviated example. First you add a new class to your project and you give it properties that correspond to all the values displayed in your dialogue box. Next you write methods to load and save a character. Where you put them depends on you and your project, but it would make sense to make them members of your class. If you do that, the Load method should be Shared so that you don't need a character instance already to load one.VB Code:
Public Class Character 'Store actual values in private variables. Private m_Name As String Private m_Age As UInt32 Private m_Class As String 'etc. 'Expose values through public properties to allow for read-only and future change of implementation. Public Property Name() As String Get Return Me.m_Name End Get Set(ByVal Value As String) Me.m_Name = Value End Set End Property 'Note that it may be better to store the date of birth and then calculate the age dynamically if real time is desired. Public Property Age() As UInt32 Get Return Me.m_Age End Get Set(ByVal Value As UInt32) Me.m_Age = Value End Set End Property 'Note that "Class" is a reserved word so to use it as an identifier it must be enclosed in square brackets. 'If specific character classes are already defined you may want to use an enumeration instead of a string. Public Property [Class]() As String Get Return Me.m_Class End Get Set(ByVal Value As String) Me.m_Class = Value End Set End Property 'etc. 'The fileName parameter is the fully qualified path to where the file should be saved, e.g. "C:\Character.xml". Public Sub Save(ByVal fileName As String) Dim serialiser As New Xml.Serialization.XmlSerializer(Me.GetType()) Dim stream As New IO.FileStream(fileName, IO.FileMode.Create) 'An exception will be thrown if the file cannot be created. serialiser.Serialize(stream, Me) stream.Close() End Sub 'The fileName parameter is the fully qualified path to the file that should be loaded, e.g. "C:\Character.xml". Public Shared Function Load(ByVal fileName As String) As Character If IO.File.Exists(fileName) Then 'Load the character from the specified file. Dim serialiser As New Xml.Serialization.XmlSerializer(GetType(Character)) '"Me" cannot be used in a shared method. Dim stream As New IO.FileStream(fileName, IO.FileMode.Open) 'An exception will be thrown if the file does not exist. 'A function contains an implicit local variable of the same name and type that can be assigned to in place of using a return statement. Load = serialiser.Deserialize(stream) stream.Close() Else 'Create a new, empty character. Return New Character End If End Function End Class
under the save and load buttons i would have it so it is linked to the class and finds the stuff it needs but i dont know how to do that
The Click event handler for your Load button will call Character.Load(<path>), which returns a Character object. You then use the properties of the Character object to populate the controls of your dialogue. Note that if there is no file at the specified location, which is likely the first time you run this, an empty Character, or at least one with default values, will be returned. Also note that Load is a Shared method, so it is (normally) called using the class name.
The Click event handler for your Save button will get a Character object (it's up to you whether you use the same one returned by Load or a new, blank object) and set its properties from the controls of your dialogue. You would then call Save(<path>) on that instance to Save the character. Note that Save is not a Shared method so it must be called on an actual Character object, e.g. myCharacter.Save(<path>).
Note that XML files from serialised objects have a specific structure. If you don't know exactly what that structure is then you should let the first run of your program create a new character and then saving it will create the file for the first time. You may also want to get the file path by some other method than passing it as an argument. You might want to set it as a constant somewhere and have the Save and Load methods retrieve it themselves. That's your choice and depends what works best in your case.
well this is a final project in my programming class practically due tomorrow for me and im not sure which case or how to implement it would work i've been programming for like 3 months
I see you are using menu items rather than buttons. I will create a demo that will update the Name, Class and Strength values and post it here very soon. It's up to you to extend the principle to include the other character properties. Check back in about 30-60 minutes.
ok
thank you very much
Here is the demo project as promised. I have used VS.NET 2003. I didn't check what version you were using.
A few points to note:This project is purely to demonstrate the serialisation techniques I suggested. Any issues, let me know.
- This project saves and loads the same file from the same location each time.
- There is no checking to make sure that required fields have been populated.
- There is no confirmation if the user tries to create a new character or load a character while they are editing one.
is there a way to have them input file name to load and save
You should use the OpenFileDialog control when loading and the SaveFileDialog control when saving. You should set the Filter property to limit the types of files they can see. Note that you don't have to use the .xml extension. You can use your own extension if you want without affecting the contents of the file. Once the user has made their choice you pass the FileName property of the dialogue box as the path to the Save or Load method.
I've update the project to use the FileDialogs. Note that they both refer to CXF files (character XML file). This is an extension that probably isn't in use by any other common application and it prevents the user trying to load some other XML file that isn't a valid character.
jmcilhinney... Been following along here.
Great info... Now I have a question.
What if I need to store more than 1 class in the file. Or even an array of classes. Saving them is easy, but how do I load certian ones? In other words... If I have classes a, b, c, d, e, and f, They're all saved to the xml file. Now if I want to load class e, how do I do that?
Also, how can I tell how many classes are stored in the file?
Even another one... how would I delete class e?
I'm sure I don't know all there is to serialisation. What I've demonstrated here is really the basics. There is definitely plenty I don't know about the use of XML in general. That said, as far as I'm aware it is not possible to deserialise part of a file. If you want one object amongst many that have been serialised to a single file, I believe you would have to deserialise the whole file and extract the single object you need. The same goes for deleting, in that you would have to deserialise, delete and then reserialise. Although I've never tried it, I don't see why you couldn't use the XmlDocument class to manipulate the XML directly. I think that this method would be more fiddly and more error-prone, though, and I don't think that it would be considerably less expensive with respect to resources and time.Quote:
Originally Posted by DanielS1324
i'm getting an error at the underlined part
VB Code:
Public Property BACost() As String Get Return Me.BACost End Get Set(ByVal Value As String) [U]Me.BACost = Value[/U] End Set End Property
"An unhandled exception of type 'System.StackOverflowException' occurred in Character Creator.exe" is the error and it's highlighted in yellow if that helps
@Kesk
By setting Me.BACost you are creating a infinite loop.
VB Code:
Private m_BACoast As String = "" Public Property BACost() As String Get Return m_BACoast 'returning the privately held m_BACost End Get Set(ByVal Value As String) m_BACoast = Value 'Setting m_BACost rather than Me.BACost End Set End Property
Exactly as grilkip says. I usually name my variables the same as their corresponding property with a "m_" prefix because it indicates the relationship between the two. You are the second person to make this mistake when adapting my code. Perhaps I will make the distinction clearer in future. If the similarity between the names confuses you at all you can certainly use a different naming convention to mine.
Edit:
The "m_" prefix is to indicate a member variable as opposed to a local one. This type of naming convention is nto so necessary these days as IntelliSense gives you that type of information on mouse-over. I still use this particular throwback because it is a convenient way to show that a variable is related to a property. If you aren't too familiar with properties, you may be wondering why they should be used at all instead of just making the variables themselves public. Properties do several things for the developer that variables do not. They can be declared read-only, so they can return a value without allowing it to be updated. They allow calculated values when getting and complex operations when setting. They also allow you to change the implementation of a property without changing the interface. They basically combine the good bits of variables and methods into a single entity.
When I put the "opendialogbox" code in it says that the opendialogbox isnt a member. how would i fix that??
You have to have added the OpenFileDialog and the SaveFileDialog to your form in the designer. I kept the default names so they should match up, or you can change their names to something more descriptive in the designer and then do a Find and Replace in the code.
jmcilhinney would you like to see a final copy when i got it done??
By all means, but make sure you post your project and not an executable. No one with sense (which I hope includes me) would download an executable from a developer forum thread. Also, if you could sign over all your royalties from distribution of the app ;)
well i'll sign over half of them cause i won't be making a dime it's pretty much a final project that i didnt even know was a final project when i started 2 months ago.
And I can't figure out why its not showing the dialog boxes now
Are you getting error messages? Is it refusing to compile? Try putting a break point somewhere before the dialogues are supposed to be shown and step through execution.
Now its just not saving to a file.
Then debug it in the IDE and use a break point as I suggested. Put the cursor on a line before the dialogue gets shown and when the debugger stops at that point use F10 to step to the next line. Use F11 to step into a property or method and Shift+F11 to step out of the current property or method. If you're still not sure you can post some code.
its saving to the .xml file in the bin folder but wont create one
Post your code for the section that saves and/or loads a Character. Just the contents of the menu item Click event handlers should be adequate.
I got it forgot to do this
VB Code:
savingCharacter.Save(Application.StartupPath & "\Character.xml")
to
VB Code:
savingCharacter.Save(Me.SaveFileDialog1.FileName))
Last thing i have left is to print the form
on something that looks like a character sheet from D&D
I'm afraid I don't know what a D&D charcter sheet looks like. I had a single experience with D&D in 1988. The simplest way to print would be to get a picture of your form as a bitmap and print that. I'm afraid printing in .NET can take a bit to come to grips with for the uninitiated. You have to do all the formatting, positioning, drawing of lines and strings yourself.
ok then lets not do that sounds like way too much for me to do on my own