When I click on a button my form needs to reload, without loosing some variables.
For example:
A game needs to be reset, but the high score variable needs to be kept to count with the next one.
"Application.Reset();" does reset the form1, but also all the variables.
Is there a way out without using databases, because we haven't learned that yet.
It can be achieved by
1.saving the data in Database
2.XML file (Write and Read)
3.Setting the properties of Class
4.Using the Static Variables**
You need to create a Class and have properties and methods in that and pass it to the form. Upon exit of the form, update your Class values with those that were changed on the form.
After that you will need to figure out "storing" the class in some sort of Stream and being able to reload your class from that stream. (XML, Binary, Protobuf, JSON) there are many ways.
You can use Settings:
http://msdn.microsoft.com/en-us/library/bb397750.aspx
and save your data on reset/closing
Related
I'm tying to migrate an Epicor V9 system with Progress/ABL code to v10 with C# code. I've got most of it done but I need a way to keep data between a BPMs pre and post processing. The comments in the original ABL code state:
Description : This function stores data from a BPM pre processing action, it does this by using a private-data (storage attribute) on the calling program...
this remains in scope during both the BPM pre and BPM post forward to procedure calls
The Epicor v9 system was set up such that the Quote form calls the BPM pre/post processing in a .p file. The .p file in turned call the code I am trying to migrate in a .i file. It looks to be a simple stack or array of strings.
What would be used in Epicor 10 to persist data between pre/post BPM processing like the .i code did in V9?
You can use CallContext.Properties for this.
In E10.0 the CallContext.Properties was of type Epicor.Utilities.PropertyBag, and items would be accessed as below:
//Add
CallContext.Properties.Add("LineRef", LineRef);
// Get
var LineRef = (string)CallContext.Properties["LineRef"];
// Remove
CallContext.Properties.Remove("LineRef");
E10.1 CallContext.Properties is now of type System.Collections.Concurrent.ConcurentDictionary, which is a .Net built in type and much better documented. However the methods to add and remove entries from it have changes as below:
//Add
bool added = CallContext.Properties.TryAdd("LineRef", LineRef);
// Get
var LineRef = (string)CallContext.Properties["LineRef"]; //Note: Do not use .ToString() this converts instead of unboxing.
// Remove
object dummy;
bool foundAndRemoved = CallContext.Properties.TryRemove("LineRef", out dummy);
To use this your class needs to inherit from ContextBoundBase and implement the only the context bound constructor or you will get 'Ice.ContextBoundBase<Erp.ErpContext>.ContextBoundBase()' is obsolete: 'Use the constructor that takes a data context'
public partial class MyInvokeExternalMethodThing : ContextBoundBase<ErpContext>
{
public MyInvokeExternalMethodThing(ErpContext ctx) : base(ctx)
{
}
In E10.1 you can put any kind of object into this, so if you have an array of strings you don't need to use the old trick of tilde~separated~values.
I don't know about using .i files from E9 but I do know how to persist data between pre and post method directives in E10. Hopefully this helps.
There are a couple of different ways to do this. If when creating the pre-process bpm you chose the "Execute Custom Code" option. You can do it directly in your code using callContextBpmData. Almost all of the field names are similar to that of the user fields that E9 used (i.e. Number01, Chracter01, Date01).
In your code if you are setting text you could simply type:
callContextBpmData.Character01 = "some text";
Alternatively you could set it directly in the bpm designer without any code. In the designer left window pane, scroll all the way to the bottom, you should see something called "Set BPM Data Field". Drag it into the design area. After dragging it into the designer area you should see the option to set a field and its value in the bottom window pane. Select the field, then when you select "value" you are taken to a window similar to baq calculated field designer. You can use static data or use the data in the business object to calculate a value.
I have the following data and objects in my program.
A DynamicObjectContainer that contains the following objects.
MeasurementParameters : DataContainer (DataContainer is the base class)
This MeasurementParameters object has many public properties, whose names I know only during runtime. I have also set up internal wiring in the DataContainer base class such that, I can access the values of the properties contained in the MeasurementParameters class using an easy to use interface.
Ex : Say I have a property in MeasurementParameters named as "pumpspeed" (type string). I can access the value of that property using this function.
MeasurementParameters.GetStringValue("pumpspeed");
I have achieved this by creating lists of delegates internally in the DataContainer object using reflection during construction of the object. (This is a one time thing.)
So far so good.
Now I am stuck at the point where I want to display these values within MeasurementParameters in a windows form.
Since I only know the property names at runtime, I have to provide the user with some method to map the property names (defined only by him in a script file) to the fixed labels within the form. So the user saves the mapping data to the table in the following format.
Entry : "pumpspeed" "label22"
I want a fast and efficient method to fetch this mapping from the database, fetch required data from the MeasuremetParameters object and display it in the windows form.
NOTE : If this is a one time operation, I have many solutions. The problem is two fold.
There are a huge number of properties in the MeasurementParameters (at around 200)
The MeasurementParameters object contains functions that update it's properties continuously. SO My windows form has to call those functions to update the MeasurementParameters object data, fetch the data and display it in the correct labels.
ALSO, this should happen in cycles of around 2 -3 times a second. (ideally)
Can anyone help me in architecting a solution for this?? A general object structure and relationship advice will also be helpful to me.
I can post the code I am using if required.
Not seeing a huge problem here
So you have Table ObjectID, PropertyName, ControlName
On opening the form / selecting the object, query them out
Build a Dictionary Keyed by PropertyName with a Value of the Label (looked up by the name of teh control from the query MyForm.Controls.FindByName(Somename). Add an OnPropertyChangedEvent to your class that throws up the name of the Property in event args then add a handler on the form
Mappings[e.PropertyName].Text = Object[e.PropertyName].GetStringValue;
Might have to twidlle with it to deal with say display controls that aren't Labels, or Panels on the Form, but it should just batter away.
I have a question concerning Monotouch.
The situation: I have 2 ViewControllers. The first (let's call it VC-A) looks similar to the contacts edit screen, meaning it has a TableView with multiple Sections each containing Buttons and TextFields. Now when the user clicks one of these Buttons, he will get to the second ViewController (VC-B), which displays a TableView containing data from the database. When the user clicks on any of these rows, VC-B will be closed and i want to display the selected database entry (string) as the title of the Button (in VC-A) which opened VC-B in the first place.
When I did an objective-C project last year, I managed to send data back down the stack by using delegates, but I haven't found a way yet how this works in Monotouch.
I have read several questions here on SO about using the AppDelegate or using singletons, but I'm not sure that this is the right way of returning data from a subview.
You can kind of copy the delegate pattern. Add a C# delegate to your VC-B that takes one parameter, some data structure.
In VC-B's "ViewWillDisappear", call the delegate it it is not null and pass the data on to it.
This way, your calling VC can get acces to the data but you don't need tight coupling between the two controllers. All it has to do, is register a delegate-method in VC-B.
As MonoTouch is .NET4 you can use Func<MyDataStructure> or Action<MyDataStructure> and don't need to use full qualified delegate types.
I have a static singleton class that I use to store "state" type data about my app - current settings and selections that are needed in many different places in the app. That's one way to approach this.
You could also pass VC-B a reference to VC-A when you create VC-B, so that it can explicitly access it's parent view and pass back values that way.
I actually prefer to use TinyMessenger for cross container calls I find this to be very very useful when you don't want to keep references to your heavy viewcontrollers around which could potentially result in memory leaks!
var messageHub = new TinyMessengerHub();
// Publishing a message is as simple as calling the "Publish" method.
messageHub.Publish(new MyMessage());
// We can also publish asyncronously if necessary
messageHub.PublishAsync(new MyMessage());
// And we can get a callback when publishing is completed
messageHub.PublishAsync(new MyMessage(), MyCallback);
// MyCallback is executed on completion
https://github.com/grumpydev/TinyMessenger
I am implementing an application and I have a few lists with some stuff in it, which is always the same, but I don't want to implement this in my real logic stuff.
Is there any way to save these items in your application? I've read some things about saving these items in a settingsfile.
Is this the best way, or there are better ways? and how can I do this?
You can save it in the application settings file
Save in XML. You can bind directly to xml in wpf. See: http://joshsmithonwpf.wordpress.com/2007/06/04/binding-to-xml/
If the content of the list is supposed to never be changed you can make them private static fields in a static class the provides a mthod to create a new instance of the list.
If the content of the list is supposed to be changed, it is a good idea to store it in the application settings file.
If the content of the list is supposed to be changed per user you should save it in the user settings file.
Depending of the content itself, I like to load the content of list into a database table. For example, a list of school would be stored in a table calle T_Ref_Schools. The Ref indicated to me that those values can be changed over time but not often.
How can I update and get values in a Windows Forms application while moving one form to other form (like cookies)?
I need to update the values to some variable and again I am going to refer stored values and need to do some calculations.
I have used cookies in ASP.NET but I am not able to find out the same concept in .NET Windows Forms (C#).
How can these issues be resolves?
You can use object references.
You can decalre a read/write Property for each variable you want to be available in another form and the use them for sharing your data.
One way to do this is to declare variables to be public, either in a global module or in any form.
public x as double
If it is declared in a module, you can access it with the variable name only. To access data declared in another form, use that form name with the variable: form1.x = 7
Another way is to declare a property in a form or other class.
A really simple way of getting cookie-like functionality would be to declare a static string dictionary in Program (Program.cs)
public static System.Collections.Specialized.StringDictionary SortOfLikeCookies = new System.Collections.Specialized.StringDictionary(); and read/write string values using Program.SortOfLikeCookies["Name"] = "Value";