Save and load List<Form> in C# - c#

I'm wondering is it somehow possible to save Form state in C# after application closing? I tried with List, and whenever I create an instance of Form that instance is added to List, and it's there until it's deleted. It works fine, and I can view, edit and delete saved forms, until Application is closed. So, considering that Form isn't serializable is there any chance to save List somehow, and load it later?

The Control and Form classes are not serializable. There's a very good reason for that, many of their property values are heavily dependent on the execution state of the program. Like Handle, very important but always different. UICues, depends on whether the user pressed the Alt key. Even simple things like Location and Size, dependent on video adapter settings and user preferences.
You would not want to serialize these properties. What you want to preserve is the data that was used to initialize the controls. Which of course entirely depends on your program, there is no commonality at all. It is therefore up to you to create a class that stores the state of your UI. You can make it serializable as needed and select your preferred way to implement serialization, there are many ways to do so. Strictly separating the view from the model in your code is normally very important to have a decent shot at making this work.

Related

C# - Variable and List accessible in whole project

Is it possible to make a variable or a List of items accessible to the whole project?
My program selects an object in one view and a I want to have access/change it another one.
I know this not the best workaround and it would be better to use a MVVM-pattern for this, but it seems a big effort to implement this properly just for this simple usecase of one ot two variables/lists.
Sharing data can be done in multiple ways.
One interesting way could be to cache the data, have a look at this for example : https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/walkthrough-caching-application-data-in-a-wpf-application?view=netframeworkdesktop-4.8
I would recommend against using any global variables, I would also recommend not using static variables either as you might open yourself up to sharing data between users for example.
In this example, when you need the data, you check if you have it in the cache, if not you load it from wherever ( db, file, api, whatever your source is) and then you simply read it from the cache wherever and whenever you require it.
If you need to update it, then you make sure you update it to whatever storage mechanism you have and then you reload the cache. This is a good way to keep things in sync when updates are needed without complicating the application, its testing and the maintenance.

Using classes with forms

I'm trying to understand whether or not it is correct to use a class when entering data into a form. I am unsure whether my understanding is correct, I don't know if I should be trying to create a new object when entering the data, or if my data should be stored in an array/file etc.
This is just for my understanding, I am just learning for myself, so don't have a specific example of what I'm trying to achieve. I am trying to understand classes, and when to use them, currently I'm messing about with c# forms in visual studio
lets say, I want to enter information into a form of all of the members of my fishing club, i.e. name, address, contact info etc. should I be attempting to create a new object of a class that contains methods for getting/setting these variables, or should I be storing these details somewhere else, in an array, or write them to a text file/excel file for example? As I'm new I think I'm struggling with the concept of classes and where to use them.
I expect that to use a class for this purpose I would have to learn to create a class instance at run time in order to create multiple instances of a class, whereas entering the data into an array I would just need to initialize the size of the array.
I'm a bit lost so any help would be very much appreciated.
Should you store those fields in objects? Yes
Should those objects be stored in a collection (like an array)? Yes
Would persisting that collection to a file make sense? Yes
Basically, you are asking to choose an alternative among things that aren't really comparable, much less mutually exclusive. As the comments suggest, make sure to read up on object oriented programming, but here's a quick explanation of each of the above:
Objects provide a structured way to store information (giving each field a name and a type, for starters) and a way for the language/compiler to enforce that structure. Storing all the related data for an entity in an object is a great idea, you almost never want to have a bunch of members for that purpose.
Arrays or more generally, collections, are groups of "things". You could have stored all that information in an array instead of an object (and then for multiple records had "parallel" arrays" but this is a very messy and amateur technique). A collection of your objects however, is a totally reasonable thing to do (you don't want object1, object2, object3 variables in your code).
Files are important because both objects and collections (which are, in and of themselves, objects) are stored in memory, they will go away when the application closes. Files (and similar, like databases) give you a way to persist them (hence such techniques being referred to as a "persistence" layer). You can then load the persisted data into a new instance of your program (say if the user restarts the computer).
Side note: Should I make methods for getting/setting these variables? No.
Just use properties (ie, public string Address {get; set;}). They provide both a backing field (at least with an auto property like the above) and are syntactic sugar for both get and set methods (which you can override with a "full" property).
As a bonus, if using WPF you can automate the population of properties from UI with data binding, but that's a question for another day :).

Reuse generic command in multiple lightswitch screens

I am designing a LightSwitch 2012 application to manage requests, and I want to be able to update the request state with the same reusable code across all of my screens. For example, A user can change a request state in the approval screen, the fulfillment screen, etc. Which are called by a button. Currently, I have a method in each of the .cs files where I need to update the request, using the partial void <ScreenCommand>_Execute() methods. I am trying to change this so I can update the code from one place instead of everywhere, and I also want to not have to copy the methods to new screens that I add a button to.
Now normally I would put this in Application.cs or somewhere else with global access, but I don't have access to the same DataWorkspace object. I also pass in the this.DataWorkspace object from the screen, which allows access to the SaveChanges() method. However, this seems a little smelly. Is there a better way to deal with this or a better place to put reusable commands that you want to be able to assign to buttons on multiple screens? Currently I have to be really careful about saving dirty data and I still have to wire everything up manually. I also don't know if the code runs in the proper context if it's in the Application.cs file.
To clarify, yes, I do want this to run client side, so I can trigger emails from their outlook inboxes and the like.
What you're trying to do is simply good programming practice, putting code that's required in more than one place in a location where it can be called from each of those places, yet maintained in just one place. It's just a matter of getting used to the way you have to do things in LightSwitch.
You can add code in a module (or a static class in C#) in the UserCode folder of the Client project. That's part of the reason the folder exists, as a place to put "user code". To do this, switch to File View, then right-click the UserCode folder to add your module/class. Add your method in the newly created module/class. You can create as many of these as you like (if you like to keep code separated), or you can add other methods to the same module/class, it's up to you.
However, I wouldn't go passing the data workspace as a parameter to the reusable method that you create. I wouldn't even pass the entity object either, just the values that you need to calculate the required state. But the actual invoking of the data workspace's SaveChanges method should remain in the screen's code. Think of the screen as a "unit of work".
In each button's Execute method (in your various screens), you call your method with values from the entity being manipulated in the screen & return the result. Assign the calculated returned value to the entity's State property (if that's what you have), then call the screen's Save method (or use the screen's Close method, passing true for the SaveChanges parameter). There's no need to call the data workspace's SaveChanges method, & you're doing things the "LightSwitch way" by doing it this way.
Another benefit of doing it this way, is that your code can now be unit tested, as it's no longer dependent on any entity.
I hope that all makes sense to you.

Web application to allow users to pick and choose objects used as building blocks?

I'm currently developing an application using ASP.NET MVC, and now I need to create an interface (web page) that will allow the users to pick and choose from a set of different objecs, the ones they'd like to use as the building blocks for constructing a more complex object.
My question is supposed to be generic, but to provide the actual example, let's say the application that will allow users to design pieces of furniture, like wardrobes, kitchen cabinets, etc. So, I've created C# classes representing the basic building blocks of furniture design, like basic shapes (pieces of wood that added together form a box, etc), doors, doorknobs, drawers, etc. Each of these classes have some common properties (width, height, length) and some specific properties, but all descend from a basic class called FurnitureItem, so there are ways for them to be 'connected' together, and interchanged. For instance, there are different types of doors that can be used in a wardrobe... like SimpleDoor, SlidingDoor, and so on. The user designing the furniture would have to choose wich type of Door object to apply to the current furniture. Also, there are other items, like dividing panels, shelves, drawers, etc. The resulting model of course would be a complete customized modularly designed wardrobe or kitchen cabinet, for example.
The problem is that while I can easily instantiate all the objects that I need and connect them together using C#, forming a complete furniture item, I need to provide a way for users to do it using a web interface. That means, they would probably have a toolbox or toolbar of some sort, and select (maybe drag and drop) items to a design panel, in the web interface... so, while in the browser I cannot have my C# class implementation... and if I post the selected item to the server (either a form post or using ajax), i need to reconstruct the whole collection of objects that were already previously chosen by the user, so I can fit the newly added item... and calculate it's dimensions, etc. and then finaly return the complete modified set of objects...
I'm trying to think of different ways of caching, or persisting theses objects while the user is still designing (adding and deleting items), since there may be many roundtrips to the server, because the proper calculation of dimentions (width, height, etc of contained objects) is done at the server by methods of my C# classes. It would be nice maybe to store objects for the currrent furniture being designed in a session object or cache object per user... even then I need to be able to provide some type of ID to the object being added and the one being added to, in a parent owner kind of way, so I can identify properly the object instance back in the server where the new instance will be connected to.
I know it's somehow confusing... but I hope this gives one idea of the problem I'm facing... In other words, I need to keep a set of interconnected objects in the server because they are responsible for calculations and applying some constraints, while allowing the users to manipulate each of these objects and how they are connected, adding and deleting them, through a web interface. So at the end, the whole thing can be persisted in a database. Idealy I want even to give user a visual representation or feedback, so they can see what they are designing as they go along...
Finally, the question is more so as to what approach should I take to this problem. Are C# classes enough in the server (encapsulating calculation and maybe generating each one it's own graphical representation back to the client)? Will I need to create similar classes in javascript to allow a more slick user experience? Will it be easier if I manage to keep the objects alive in a session or cache object between requests? Or should I just instantiate all objects that form the whole furniture again on each user interaction (for calculation)? In that case, I would have to post all the objects and all the already customized properties every time?
Any thoughts or ideas on how to best approach this problem are greatly appreciated...
Thanks!
From the way you've described it, here is what I'm envisioning:
It sounds like you do want a slick looking UI so yes, you'll want to divide your logic into two sets; a client-side set for building and a server-side set for validation. I would get heavy on the javascript so that the user can happily build their widget disconnected, and then validate everything once it's posted to the server.
Saving to a session opens a whole can of webfarm worms. If these widgets can be recreated in less than a minute (once they've decided what they like), I would avoid saving partials all together. If it's absolutely necessary though, I would save them to the database.
If the number of objects to construct a widget is reasonable, it could all come down at once. But if there are hundreds of types of 'doors' you're going to want to consider asynchronous calls to load them, with possible paging/sorting.
I'm confused about your last part about instantiating/posting all objects that form the whole furniture. This shouldn't be necessary. I imagine the user would do his construction on his client, and then pass up a single widget object to the server for validation.
That's what I'm thinking anyway... by the way, hello StackOverflow, this is my first post.
You might want to take a look at Backbone.js for this kind of project. It allows you to create client-side models, collections, views and controllers that would be well suited to your problem domain. It includes built in Ajax code for loading/saving those models/collections to/from the server.
As far as storing objects before the complete object is sent to the server, you could utilize localStorage, and store your object data as a JSON string.

Implement a "cancel" button on forms that use databinding and nhibernate

I use nhibernate to access a mysql database, and I have many -winforms- forms using databinding to modify properties of those objects. There are many –nhibernate- objects created/deleted also during the time those forms are used.
I need to implement a "Cancel" button on those forms.
I can defer the creation/deletion of objects on the database (nhibernate’s Session.Save/Delete) to the moment the form is closing. But I don’t know what to do about the changing of loaded objects’ properties directly by the user (changed by winforms databinding) or the adding/removing of objects to the related objects collections.
I’m not a nhibernate expert at all. Is there any way to mark a referenced object as “not loaded yet”, to force a refresh from the DB the next time it is referenced in any way (collections and properties) without losing the reference (kind of return the reference to the proxy object to the initial state, before the first load from the DB)?
I’m not a winforms expert at all neither. How can I know which objects where changed through databinding?
I guess a simple approach would be to use INotifyPropertyChanged on your entities and INotifyCollectionChanged or use a collection that already implements it. Then you can subscribe to those events and, at least know, if they had changed.
In any case this is an aspect of presentation I really would like to hear some opinions on.

Categories

Resources