I have small number of GUI attribute that i need to save in my application.
The attribute are simple ( windows size, window color, ext... ) and they need to be store in file ( can be XML or binary ).
I don't sure i know what is the fest and best way to write the code ?
Is it simple XML or serialization ?
Is there some example ?
Thanks.
Store the value in the web.config file. Here is an example:
<appSettings>
<add key="size" value="100" />
Edit: Since it looks like its a windows app, an App.config file can be used.
I would recommend to use IsolatedStorage to store application runtime settings:
IsolatedStorageSettings appSettings= IsolatedStorageSettings.ApplicationSettings;
appSettings.Add(<Control.PropertyName>, <Value>);
This is my preferred way of storing application settings, hope it helps
public class Settings
{
public int WindowWidth { get; set; }
public int WindowHeight { get; set; }
public int FullscreenAsDefault { get; set; }
}
then in whichever main class is applicable for the type of application:
public Settings Settings { get; set; }
public void OnOpen()
{
if ( !File.Exists( "Settings.xml" ) )
{
// init settings
this.Settings = new Settings()
{
FullscreenAsDefault = false,
WindowHeight = 500,
WindowWidth = 700
};
}
else
{
// load settings
XmlSerializer xmlSerializer = new XmlSerializer( typeof( Settings ) );
Settings = xmlSerializer.Deserialize( new FileStream( "Settings.xml", FileMode.Open ) ) as Settings;
}
}
public void OnClose()
{
// save settings
XmlSerializer xmlSerializer = new XmlSerializer( typeof( Settings ) );
xmlSerializer.Serialize( new FileStream( "Settings.xml", FileMode.Create ), this.Settings );
}
If they're stored as properties in a class, such as Settings you could serialize this to disk (either binary or xml your choice).
Deserialize this file to get your Settings object back when the application starts. If the file doesn't exist, create a new Settings object and serialize the default values.
I would recommend XML because it's "human readable" and can be manipulated/view with normal tools.
The really easy method is to use a DataContractSerializer. The link shows how to define the entity to serialize and how it can be easily serialized. There is also ISerialiazable and XmlSerializer, etc, but why bother when DCS is so easy? :-)
You could go for the plain old INI files, for storing non-sensitive values. You could use Nini (http://nini.sourceforge.net/) to read and write to INI files. .NET framework doesn't provide any inbuilt libraries to handle INI files.
Related
I'm making an educational game (Windows 10 UWP, C# + XAML) and I need to store user information (in particular, their current score) and retrieve it when they start the app again. I've found a way to do this (see code below) but I have no idea if this is a normal solution to this problem. I'm currently creating a txt file and storing and retrieving data in/from it. Are there more common, or simpler ways to do this?
Here's what I'm currently doing:
Create the file:
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.CreateFileAsync("nameOfTextFile.txt", CreationCollisionOption.OpenIfExists); //other options are ReplaceExisting
Open the file:
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.GetFileAsync("nameOfTextFile.txt");
Write text to the file:
await FileIO.WriteTextAsync(sampleFile, "Put the added text here");
Read text from the file:
string someVariableName = await FileIO.ReadTextAsync(sampleFile);
-Thanks in advance for any help!!
While the file-based approach is valid, there are easier ways, at least for simple data: You can use roaming (or local) settings. Roaming settings are roamed between devices, as long as their size don't exceed 64K, and would carry the score from the user's desktop to the user's phone, for example. Local settings stay on the machine.
Settings are easy to use:
IPropertySet propertySet = ApplicationData.Current.RoamingSettings.Values;
// Get previous score (or 0 if none)
int score = (int)(propertySet["Score"] ?? 0);
// ...play game...
// Set updated score:
propertySet["Score"] = score;
The way I go about doing projects and settings like this is creating a propery setting in Visual Studio, then Setting and Getting the setting / Value.
You can access this by going to the application properties.
This allows access to read,write, and save information / onload restore information.
Some Informational Links:
https://msdn.microsoft.com/en-us/library/bb397755(v=vs.110).aspx
and (Suggested)
https://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
OK, so here goes an example of using a class to store your settings in.
There are many, many more ways you could do this. Too many to list.
Create a settings class:
public class YourSettingsClass
{
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserScore { get; set; }
}
Create an AppSettings helper
public AppSettings
{
private static YourSettingsClass _settings = new YourSettingsClass();
public static string UserFirstName
{
get { return _settings.UserFirstName; }
set { _settings.UserFirstName = value; }
}
public static string UserLastName
{
get { return _settings.UserLastName; }
set { _settings.UserLastName = value; }
}
public static string UserScore
{
get { return _settings.UserScore; }
set { _settings.UserScore = value; }
}
public static void SaveSettings()
{
// Now, use your "settingsfile.xml" (or whatever you're saving as)
// to write your settings to from your _settings static field object.
// I'll let you have a play as to how you want to do this...
}
public static void LoadSettings()
{
YourSettingsClass tempSettingsClass = new YourSettingsClass();
// Now, use your "settingsfile.xml" (or whatever you've saved it as)
// to load in your settings and assign to your tempSettingsClass variable.
// I'll let you have a play as to how you want to do this...
// Assign the settings from your loaded object.
_settings = tempSettingsClass;
}
}
Now, from any other class, you can call AppSettings.LoadSettings(). You could do this on App Startup, or on-demand.
When you've loaded the settings in, just reference AppSettings.UserFirstName or whatever property you want to either get the value or set the value.
When you're ready to, you can then save the settings back to the XML file on disk, through AppSettings.SaveSettings().
I've purposely omitted the code for loading and saving from the storage, and for se/deserializing class objects as I haven't got any UWP components on this PC and I've done this all from memory so I don't want to put anything in to throw you off.
Plus it's a little more learning (even trial/error) for you to do.
Lastly
In the getters for your AppSettings static properties you could also do a null or string.IsNullOrWhiteSpace check for the _settings' property in question, and call the LoadSettings() method if so.
This would save you having to manually call it in-code elsewhere.
Useful links
XmlSerializer and how to use the Serialize method
All about what you can do with the FileIO.WriteTextAsync
Not an article, but a similar question: UWP C# Read & Write XML File
I really hope this helps, somewhat.
Good luck!
This question already has answers here:
How can I save application settings in a Windows Forms application?
(14 answers)
Closed 7 years ago.
what is the best way to save configuration data in c# application?
note that those data maybe changed dynamically.
as i know, ConfigurationManager class can be used. but i heard that this is not good way to do that.
A simple way is to use a config data object, save it as xml file with the name of the application in the local Folder and on startup read it back.
Here is an example to store the position and size of a form.
The config dataobject is strongly typed and easy to use:
[Serializable()]
public class CConfigDO
{
private System.Drawing.Point m_oStartPos;
private System.Drawing.Size m_oStartSize;
public System.Drawing.Point StartPos
{
get { return m_oStartPos; }
set { m_oStartPos = value; }
}
public System.Drawing.Size StartSize
{
get { return m_oStartSize; }
set { m_oStartSize = value; }
}
}
A manager class for saving and loading:
public class CConfigMng
{
private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
private CConfigDO m_oConfig = new CConfigDO();
public CConfigDO Config
{
get { return m_oConfig; }
set { m_oConfig = value; }
}
// Load configfile
public void LoadConfig()
{
if (System.IO.File.Exists(m_sConfigFileName))
{
System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
Type tType = m_oConfig.GetType();
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
object oData = xsSerializer.Deserialize(srReader);
m_oConfig = (CConfigDO)oData;
srReader.Close();
}
}
// Save configfile
public void SaveConfig()
{
System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
Type tType = m_oConfig.GetType();
if (tType.IsSerializable)
{
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
xsSerializer.Serialize(swWriter, m_oConfig);
swWriter.Close();
}
}
}
Now you can use it in your form in the load and close events:
private void Form1_Load(object sender, EventArgs e)
{
// Load config
oConfigMng.LoadConfig();
if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
{
Location = oConfigMng.Config.StartPos;
Size = oConfigMng.Config.StartSize;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// Save config
oConfigMng.Config.StartPos = Location;
oConfigMng.Config.StartSize = Size;
oConfigMng.SaveConfig();
}
And the produced xml file is also readable:
<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<StartPos>
<X>70</X>
<Y>278</Y>
</StartPos>
<StartSize>
<Width>253</Width>
<Height>229</Height>
</StartSize>
</CConfigDO>
Very simple, or what so you think?
Use the built-in settings mechanism. But leave the configuration manager alone and use your settings like
Properties.Settings.Default.x
There is nothing wrong in using the ConfigurationManager (web.config/app.config).
For different types of configuration data, I recommend the following;
Never-changing read-only configuration data
Hardcode in application or use (assembly-level) attributes. This
requires a recompile/re-installation of app when configuration-data
changes.
Almost never-changing read-only configuration data
Use the <appSettings>, <connectionStrings> or other sections in web.config/app.config (Often requires a restart of app when changed, especially when configuration-data is read only during startup)
Server-side writable configuration data maintained in application
Use a database or a file in C:\ProgramData\<name of your company>\<name of your app>
Client-side writeable configuration data maintained in application (desktop-apps)
Use a file in C:\Users\<clients login name>\AppData\Local\<name of your company>\<name of your app>\. If you need configuration data to be available on other computers (using the same AD domain), use the LocalRoaming folder under AppData instead (don't place too much configuration data in files placed here, tho because they need to be transferred between computers)
Good evening; I have an application that has a drop down list; This drop down list is meant to be a list of commonly visited websites which can be altered by the user.
My question is how can I store these values in such a manor that would allow the users to change it.
Example; I as the user, decide i want google to be my first website, and youtube to be my second.
I have considered making a "settings" file however is it practical to put 20+ websites into a settings file and then load them at startup? Or a local database, but this may be overkill for the simple need.
Please point me in the right direction.
Given you have already excluded database (probably for right reasons.. as it may be over kill for a small app), I'd recommend writing the data to a local file.. but not plain text..
But preferably serialized either as XML or JSON.
This approach has at least two benefits -
More complex data can be stored in future.. example - while order can be implicit, it can be made explicit.. or additional data like last time the url was used etc..
Structured data is easier to validate against random corruption.. If it was a plain text file.. It will be much harder to ensure its integrity.
The best would be to use the power of Serializer and Deserializer in c#, which will let you work with the file in an Object Oriented. At the same time you don't need to worry about storing into files etc... etc...
Here is the sample code I quickly wrote for you.
using System;
using System.IO;
using System.Collections;
using System.Xml.Serialization;
namespace ConsoleApplication3
{
public class UrlSerializer
{
private static void Write(string filename)
{
URLCollection urls = new URLCollection();
urls.Add(new Url { Address = "http://www.google.com", Order = 1 });
urls.Add(new Url { Address = "http://www.yahoo.com", Order = 2 });
XmlSerializer x = new XmlSerializer(typeof(URLCollection));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, urls);
}
private static URLCollection Read(string filename)
{
var x = new XmlSerializer(typeof(URLCollection));
TextReader reader = new StreamReader(filename);
var urls = (URLCollection)x.Deserialize(reader);
return urls;
}
}
public class URLCollection : ICollection
{
public string CollectionName;
private ArrayList _urls = new ArrayList();
public Url this[int index]
{
get { return (Url)_urls[index]; }
}
public void CopyTo(Array a, int index)
{
_urls.CopyTo(a, index);
}
public int Count
{
get { return _urls.Count; }
}
public object SyncRoot
{
get { return this; }
}
public bool IsSynchronized
{
get { return false; }
}
public IEnumerator GetEnumerator()
{
return _urls.GetEnumerator();
}
public void Add(Url url)
{
if (url == null) throw new ArgumentNullException("url");
_urls.Add(url);
}
}
}
You clearly need some sort of persistence, for which there are a few options:
Local database
- As you have noted, total overkill. You are just storing a list, not relational data
Simple text file
- Pretty easy, but maybe not the most "professional" way. Using XML serialization to this file would allow for complex data types.
Settings file
- Are these preferences really settings? If they are, then this makes sense.
The Registry - This is great for settings you don't want your users to ever manually mess with. Probably not the best option for a significant amount of data though
I would go with number 2. It doesn't sound like you need any fancy encoding or security, so just store everything in a text file. *.ini files tend to meet this description, but you can use any extension you want. A settings file doesn't seem like the right place for this scenario.
I have a form with information in it that the user enters, i want to save this to XML... i'm fairly new to programming but have read XML is the best thing to use. How would i go about it? If it helps im using Sharp Develop as an IDE. Current it has 10 text boxes and 10 datetimepickers.
The easiest thing would be to create a class that stores those 10 values as properties and use xml serialization to convert it to XML, then store it to the file system.
Here's a tutorial: http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization
More Detail:
This is super basic Object Oriented/Windows Forms stuff.
Create a Class that stores each of the values:
public class Values{
public string YourFirstValue { get; set;}
public DateTime YourSecondValue { get; set;}
...
}
and of course you'd want names that map to their actual meanings, but these should suffice for now.
Then, when clicking a button on your form, store the values in that class:
void Button1_OnClick(object sender, EventArgs args){
Values v = new Values();
v.YourFirstValue = this.FirstField.Text;
v.YourSecondValue = this.YourSecondField.Value
...
SaveValues(v);
}
Then implement the SaveValues method to serialize the xml using XmlSerializer for the serialization and StreamWriter to store the result to a file.
public void SaveValues(Values v){
XmlSerializer serializer = new XmlSerializer(typeof(Values));
using(TextWriter textWriter = new StreamWriter(#"C:\TheFileYouWantToStore.xml")){
serializer.Serialize(textWriter, movie);
}
}
I found something similar to what I need here:
http://www.codeproject.com/KB/cs/PropertiesSettings.aspx
But it does not quite do it for me. The user settings are stored in some far away location such as C:\documents and settings\[username]\local settings\application data\[your application], but I do not have access to these folders and I cannot copy the settings file from one computer to another, or to delete the file altogether. Also, it would be super-convenient to have the settings xml file right next to the app, and to copy/ship both. This is used for demo-ware (which is a legitimate type of coding task) and will be used by non-technical people in the field. I need to make this quickly, so I need to reuse some existing library and not write my own. I need to make it easy to use and be portable. The last thing I want is to get a call at midnight that says that settings do not persist when edited through the settings dialog that I will have built.
So, user settings are stored god knows where, and application settings are read-only (no go). Is there anything else that I can do? I think app.config file has multiple purposes and I think I once saw it being used the way I want, I just cannot find the link.
Let me know if something is not clear.
You could create a class that holds your settings and then XML-serialize it:
public class Settings
{
public string Setting1 { get; set; }
public int Setting2 { get; set; }
}
static void SaveSettings(Settings settings)
{
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenWrite(SettingsFilePath))
{
serializer.Serialize(stream, settings);
}
}
static Settings LoadSettings()
{
if (!File.Exists(SettingsFilePath))
return new Settings();
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenRead(SettingsFilePath))
{
return (Settings)serializer.Deserialize(stream);
}
}