Maybe the some if it is obsolete.
One possibel problem is also that I have a List in one class.
Maybe I have to use Serialization but not really sure when that is needed.
Anyway, here my code. I don't get any errors but it doesn't work.
The folder is made and I can save a .dat-file but I can't load the list.
private void Form1_Load(object sender, EventArgs e
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
BinaryReader customerBinaryIn = new BinaryReader(new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read));
while (customerBinaryIn.PeekChar() != -1) //Så länge det inte är slut på tecken
{
Kund kund1 = new Kund();
kund1.PersonNr = customerBinaryIn.ReadInt32();
kund1.Name = customerBinaryIn.ReadString();
CustomerList.Add(kund1);
}
customerBinaryIn.Close();
}
public void sparaKund()
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
BinaryWriter customerBinaryOut = new BinaryWriter(new FileStream(path, FileMode.Create, FileAccess.Write));
foreach (Kund K in CustomerList)
{
customerBinaryOut.Write(K.PersonNr);
customerBinaryOut.Write(K.Name);
customerBinaryOut.Write(K.Loan.ToString()); //Not sure about this...
}
customerBinaryOut.Close();
}
private void button1_Click_1(object sender, EventArgs e) //close button
{
sparaKund();
Environment.Exit(1);
}
VulpesPosted Apr 16, 2012, 2:00 PM
Here's a very simple example showing the steps needed:
VulpesPosted Apr 23, 2012, 6:39 AM
However, XML serialization can still serialize a List
In case it helps, I've updated my simple example to include the situation where the List includes a TextBook which is a child class of Book:
Lars PerssonPosted Apr 22, 2012, 7:18 PM
Vulpes:
Well, it seemde as if the books included had to be public so I changed that.
Now I get (translated by me)
The type CSharpProjekt.FaktaBok was not expected. Use the attribute XmlInclude or SoapInclude if you wan´t to use types that are not static
I found this: http://www.johnsoer.com/blog/?tag=the-type-was-not-expected-use-the-xmlinclude-or-soapinclude-attribute-to-specify-types-that-are-not-known-statically
And what I have is a book-class, three classes inherits from that class. The base book-class also have a variable of type customer-class where I save the customer who is borrowing the book. This point to null if no one has borrowed it.
I guess this could be the problem. But do that mean that I can't save all the books in one List?
Sam HobbsPosted Apr 22, 2012, 7:10 PM
Lars PerssonPosted Apr 22, 2012, 5:54 PM
Wanted to make sure I didn´t do any obvious error.
Thanks anyway.
VulpesPosted Apr 22, 2012, 5:42 PM
Lars PerssonPosted Apr 22, 2012, 5:05 PM
I had finally had the time to test you code and it works fine with one list but not with two.
I think I´ve made some error.
This is on top in main:
List
List
static string dir = @"C:\Bibliotek\";
string path = dir + "Kunder.xml";
string path2 = dir + "Books.xml";
XmlSerializer xs = new XmlSerializer(typeof(List
XmlSerializer xs2 = new XmlSerializer(typeof(List
I have a list of books and a list of customers.
Two paths including the name of the file to create.
Then two serializers.
Then I have this method when I close the application.
public void sparaKund()
{
using (Stream s = File.Create(path))
{
xs.Serialize(s,CustomerList);
}
using (Stream s2 = File.Create(path2))
{
xs2.Serialize(s2, BookList);
}
}
And this when I start.
private void Form1_Load(object sender, EventArgs e)
{
// deserialize to a new list
using (Stream s = File.OpenRead(path))
{
//list2 = (List
CustomerList = (List
}
if (File.Exists("Books.xml"))
{
using (Stream s2 = File.OpenRead(path2))
{
BookList = (List
}
}
}
One problem is that the second file "books.xml" can´t be created. Or rather, it is created but empty.
I have also tried to solve the problem if the file I´m trying to load doesn´t exist.
Lars PerssonPosted Apr 17, 2012, 6:16 AM
Again I disagree. You can MAP objects to a realtional database. One technology to do this is LINQ.
Maybe we are talking about different things.
theLizardPosted Apr 17, 2012, 12:13 AM
In some cases sending a complete object with all its properties, filled or otherwise, to another object is fine, in others it is not.
I can only give my approach and experience but one of the first things I do with any new language I learn is to create custom controls inherited from the standard controls, this allows me to add additional properties events and methods which then allows me to go directly to the record in a database that I want to access.
More importantly,creating custom controls / components like this allows me to understand the language and it limitations.
If we take what Lars wants to do and compare that with my approach we have
1. A custom drop down Combo Box that has the item values of a particular field in the database, it has extended propertie, one of which is a RecordId property linked to the lists ItemIndex.
2. I have an Database Access component (object) and a Control Agent component (object) on the form.
The Database Access component manages all read / writes to the database so all it needs to know is the database, the driver to use and the table that will be affected but does not need to know this in advance.
To fill the combo box with the values I want to see in the list I simply ask the dbObject to fill the combo box like dbObject->FillComboBox("SELECT id, name FROM customer ORDER BY name", theComboBoxToFill);
The Control Agents' job is to map the controls on the form to fields of the database table, set their values or show their values in their designated control, it also dynamically creates the INSERT or UPDATE sql statements for the database object.
I am sure that you will realize, you cannot have a custom control agent for each and every form that you may or may not have in a project so the control agent object must be independent of any database table or in fact any database type, SQL Server, MySql, Access, SQLite, Excel ... You could say this is a bit like what MS does with binding.
The difference here is that I have total control over what the agent does and it is not just binding controls to their field definition, it also handles the movement from one field to another, it handles whether or not you can leave a field empty as well as allowing decimal digits and not and if the first letter of each word in text controls need to be in upper case or not.
The agent also has a recordid property and can be linked to another agent on another form so that direct access to the other forms private and public methods, events and member variables are available.
When opening a form, the record id is parsed to the agent of the new form and because the agent on the other form knows what to do it is able to get the record, file the class, say customer and show the values in their designated controls with simple calls, maybe less than what you do in C# to get and bind to a grid or other..
eg.
agent->GetFieldDefs(dbObject, "myTable", OwnerContainer);
//this finds all the controls on the container, maps them to the table finally sorting them in to a data entry order irespective of ordinal position in the database.
The next instruction is something like this
agent->FillControls("SELECT * FROM customer WHERE id = " + IntToStr(agent->RecordId), ownerContainer);
//What this does is, populate the controls on the form that are mapped to the database field, if its a float value, it converts the float to a string value, if its a TINYINT value, it checks or unchecks check boxes.
So with two lines of code using the custom objects, I have all the flexibility I need, I never need to write code to do things like
myCustomerObject.FirstName = TextBox1.Text or TextBox1.Text = myCustomerObject.FirstName;
or TextBox2.Focus();
The agent does this for me.
By having these types of objects on a form, you are able to have multiples of them so that you can address two or more entirely different database (SQL Server, MySql etc) on the same form having the same table structure (for maybe migrating from one DB to another) and even showing them in the one set of controls in one container or a second set in another container on the same form.
The point I am trying to make here is that OOP is the way to go and how you design your classes to manage OOP is important for you to maximize your development efforts without having to deal with mundane things like filling controls, updating databases or moving between fields.
The other thing about the agent and db object is that I do not need to create a class object for each table, that is handled by a generic class which has properties to describe field name, type, size, ordinal position etc.. in this way, I can access the field value by its name in the Fields class object which is a vector of field defenitions.
What Lars wants to do using this approach would be a walk in the park, no defining of a customer class, no need to assign values to controls, no need to worry about saving the field object values to the database.
Cheers..
Sam HobbsPosted Apr 16, 2012, 11:19 PM
A binary file is not object-oriented. Databases are more object-oriented than binary files. Objects can use a binary file format to persist data and they can use a database table to persist data.
Sam HobbsPosted Apr 16, 2012, 10:50 PM
In my sample, the Program class does nothing with the UI except create the main form and run the message loop, the same as any Forms application. The thing that my sample code does that is more than what the Program class does when a Forms application is generated is that it reads and writes the Customer objects into and from a BindingList. A BindingList is essentially a List. What the main form does is relatively unimportant for the purposes of the sample; Lars was asking about using a ListBox but I used a DataGridView. To answer the question about whether all the Customer fields would exist in the DataGridView, the answer is yes; all fields would be be put in the DataGridView by default. Actually, only the ones with public access and I think only properties but I forget about whether the requirement is for only properties.
The important thing that my sample shows relevant to the question in that thread is that Form2 passes a Customer object to Form2. The Customer object can have two properties or it can have 200 properties but Form1 only needs to pass the object to Form2. The object is an object in the Customers collection; it is not a control.
theLizard, have you used MFC? It has a document/view architecture. It emphasizes separation of the document and the view but I think it is too cumbersome in some ways. I think the designers of the IDE are too influenced by VB and is an over-reaction to the cumbersomeness of MFC. MFC was Microsoft's initial attempt at object-oriented programming and I assume it influenced .Net but I think Microsoft gave too much control of the IDE to VB people that are not experienced with object-oriented programming.
theLizardPosted Apr 16, 2012, 10:44 PM
I guess you can make anything an object, a blade of grass is an object, we can define the properties of a blade of grass as an class object, so how do you save the blade object into a database without mapping the properties of the object to their respect fields in a database table, relational or otherwise?
It may be (I doubt that) common to use XML as a data source but I imagine a text based XML file of 1 or 2GB in size would take a hell of a long time to find who borrowed "One Flew Over The Cuckoo's Nest" from the library but I can't say if this is true because I do NOT use XML for anything, one thing for sure is that library borrowing systems do not use XML, some use propriety binary files others use SQL Server
Since you know about the technologies (I admit I do not know the technologies you are referring to) can you explain what these are so that we may learn all about them.
"Serializing data using a binary format might be more object-oriented but it is used much less often."
Are you sure about this, I think SQL Server MDF database files are binary files, maybe some one can confirm this...
Sam HobbsPosted Apr 16, 2012, 9:45 PM
When you were to learn about the technologies I have described, you will learn that they can make databases into objects. You just are not familiar with the technology.
It is true that you could write classes that know how to read and write themselves. If you read the articles in this web site I am confident you will find articles about doing that. It is possible to do that using XML. The advantage of using XML is that then the data can be used by other software. If you use a binary format then the data is less compatible with other software.
There is so much to learn that you must make decisions of what to learn. Both databases and XML are good choices of things to learn. Serializing data using a binary format might be more object-oriented but it is used much less often. It is much more common to serialize data using XML than in a binary format. You can use XML or a text-only format and still be object-oriented.
I did not say that databases are as object-oriented as all other formats, but they are as object-oriented as all of them that are commonly used. There is a reason for that, and when you add to that the fact that technology exists to create an object-oriented layer for databases, there is not much of an argument against databases.
theLizardPosted Apr 16, 2012, 9:07 PM
Correct.
Lars PerssonPosted Apr 16, 2012, 9:00 PM
You have to map the objects so they can be save into a relational database.
Otherwise you have to use a Object database:
http://en.wikipedia.org/wiki/Object_database
Sam HobbsPosted Apr 16, 2012, 8:53 PM
Lars PerssonPosted Apr 16, 2012, 8:44 PM
Well, I was thinking about relational databases which are not object oriented. Then you have to use some technology to translate the objects, like LINQ.
I also know about the 3-tier pattern but this is not a professionell program.
theLizardPosted Apr 16, 2012, 7:21 PM
"And now think about what my sample code does. It reads the data in the Program class into a class separate from the UI"
Q. In your program class, does it update the controls on your UI or does the UI update its own controls using the members of your other class.
"I won't say what I really think about a form getting the controls of another form, but it is the type of thing that can increase an application's complexity exponentially."
Q. Why not, it would help others decide if accessing controls of other forms is bad programming or not, you have certainly.
In your example code RE How to access a controll in another form you have this
DialogResult dr = f.ShowDialog();Q. (I know this is an example piece of code) Would the dataGridView contain ALL the members of the customer class or just a sub set, if it is a sub set when do you get the remainder of the set to parse to the other form for it to perform the maintenance tasks for the customer record.
In the other thread the question relates to getting a value in a list box to the other form so that it can load the customer record into its own form controls for maintenance and clearly, a list box does not have all the customer class members values, so what you are saying is that form 1 should load the customer class first in a datagrid view (or something else that has ALL the field values) then send the customer class to the other form, is it not more appropriate that the maintenance form be the one that loads the customer class members letting the other form only deal with a list box, datagridView or even a tree view of customer record references.
I do this all the time (in C++), I have custom combo boxes, text boxes, tree views etc that load on demand field values like names and record id and simply parse the record id to the maintenance form for IT to load and show control values.
None of my forms actually assign customer members into their relevant controls, that is done by a class I call a ControlAgent and it does not care whose form controls it fills, it knows what controls are on the form to be filled and I do not tell it what they are it gets them at form initialization.
This actually falls in line with what you have described as DAL, BLL and UI which as you say is good practice, write once use many is my motto.
However, after saying this, there are times that you DO and is acceptable to access controls and public and private members on other forms especially when they are inter related.
Sam HobbsPosted Apr 16, 2012, 5:21 PM
And now think about what my sample code does. It reads the data in the Program class into a class separate from the UI.
I do realize that it seems to not be object-oriented to separate objects in to three pieces (DAL, BLL and UI) but it is what is commonly done. The Visual Studio IDE does lead beginners toward putting all three into the form but Microsoft also offers and supports other technology that most professionals would use. I truly think that three-tier technology and the others like it are used more often by experienced developers than the technique of a form getting the controls of another form. I won't say what I really think about a form getting the controls of another form, but it is the type of thing that can increase an application's complexity exponentially. It is the type of thing that makes software difficult to maintain and I sure do have experience maintaining software that has been heavily modified by many people. If object-oriented is the goal, then absolutely do not write code that gets another form's controls.
Another methodology is Model-View-Controller (MVC). I think it is more commonly used for online applications but I am not sure.
Lars PerssonPosted Apr 16, 2012, 4:46 PM
I know about databases but when this was done in Java it was an exercise in OOP.
Why should you not use binary-format?
Sam HobbsPosted Apr 16, 2012, 4:32 PM
There are many articles about serializing/unserializing and persisting data. Look in this web site for articles. There are some about using CSV and text formats but there are better formats. I wrote an article about using XML but it is useful for just one class. So in other words my article would show how to serialize (write?) and unserialize (read?) the customers in a file but you would need anohter file for the books and such. XML is a good chice since you can put all the data in one file; you can save all the customers and books in one file using XML.
You can use a tab-delimited file as I show in your other thread. There are many reasons why that is not a good solution but if you can explain why you are not using tab-delimited files then perhaps I can explain how to solve the problem.
I suggest using a database but I assume you are not ready to do that. The next best choice is XML. I think a aqb-delimted file would be good for educational purposes.
Also, it is likely best to not store the data in a binary format. For this project I think it is best to convert numbers and dates to/from text.