Windows Phone 7, IsolatedStorageSettings "Remove()" not working, a bug? - c#

I'm using IsolatedStorageSettings class in my Windows Phone 7 project as a key-value store to remember user preferences and login credentials in my app.
The problem is, when I invoke Remove(string) method with the key and then I use Save() method to persist changes. Remove() method returns true, that means value is deleted. But when I try to get the value next time, I see that it is still there and not deleted.
Here's the code I use for deletion:
if (isolatedStore.Contains(key))
{
isolatedStore[key] = null;
}
bool del = isolatedStore.Remove(key);
isolatedStore.Save();
Here's how I get isolatedStorage instance:
private IsolatedStorageSettings isolatedStore =
IsolatedStorageSettings.ApplicationSettings;
Where do you think the problem is?

I found this block in the following link. I haven't tried to remove a key the way you're doing, though. http://social.msdn.microsoft.com/Forums/en/windowsphone7series/thread/17514c94-1f59-47b4-bb78-99694bfbb6b2
public static void DeleteObject(string key)
{
IsolatedStorageSettings.ApplicationSettings.Remove(key);
}

Related

How to implement states on a windows form appliaction

I am developing a c# windows form application. In my application i have 3 forms (main form that has a list box and two buttons (Check in and check out), check in form and the check out form). On the main form, the list box contain user names, if a user select their name for the first time, the check in button must be enabled for the user to check in... But if the user checks in and then closes the application, when they reopen it, the button check out should be enabled and check in disabled.
I have been told to use the application/user states, but since I'm new in programming, i don't know how to implement the windows form states.
What should i do?
Thank you
There is no such thing as "Windows Forms states". You have several options to implement somthing like this, among which are:
Use a database (this makes sense if you have a varying number of users and a database server available)
Use user settings (this is a builtin mechanism of the .NET framework, but may not be suitable for lots of users)
Use a simple XML file to store the states of all users.
All three solutions require you to sort of "get into things". Write more about what you have available (database server, etc.) or whether you want a fixed number of users and I can extend this answer to help you get started.
I'm going to line out how to do number 2:
Create a little helper class that assigns a state to a user name:
public class UserState
{
public string UserName { get; set; }
public bool CheckedIn { get; set; }
public override string ToString() { return String.Format("{0}={1}", UserName, CheckedIn); }
}
This class allows you to store a user name and the checked in state and by calling ToString() get a value in the form "user=false".
Then, create a user scoped application setting (go to settings-tab of project settings and add a new setting of type System.Collections.Specialized.StringCollection) named UserStates. You can access this setting from code as Properties.Settings.Default.UserStates. It is basically a list of strings.
To add and persist a new entry you could do this:
UserState state = new UserState() { UserName = "Test", CheckedIn = false };
Properties.Settings.Default.UserStates.Add(state.ToString());
Properties.Settings.Default.Save();
The state for user "Test" (and the previously existing entries) are now stored across program restarts.
Now the idea is to build a list of users and their states when starting the program and to store this list when exiting.
Declare this as a member variable in the class:
private List<UserState> userStates = new List<UserState>();
Do the following in the form's OnLoad event:
if (Properties.Settings.Default.UserStates == null || Properties.Settings.Default.UserStates.Count == 0)
{
// Add your users to the collection initially. This is the first
// run of the application
userStates.Add(new UserState() { ... });
...
}
else
{
// Each line in the setting represents one user in the form name=state.
// We split each line into the parts and add them to the internal list.
for (int i = 0; i < Properties.Settings.Default.UserStates.Count; i++)
{
string stateLine = Properties.Settings.Default.UserStates[i];
string[] parts = stateLine.Split('=');
userStates.Add(new UserState() { UserName = parts[0].Trim(), CheckedIn = Boolean.Parse(parts[1].Trim()) });
}
}
This creates a new entry in an internal list of users for each stored line in the collection setting.
When a button is clicked, change the state in the respective UserState object in the list.
Do the following in the form's OnClose event:
// Create the collection from scratch
Properties.Settings.Default.UserStates = new System.Collections.Specialized.StringCollection();
// Add all the users and states from our internal list
foreach (UserState state in userStates)
{
Properties.Settings.Default.UserStates.Add(state.ToString());
}
// Save the settings for next start
Properties.Settings.Default.Save();
This persists the current list of user states to the setting.
Please note: I have tested this in Visual Studio now and it works. I leave the question of how to map the list box entries to the UserState objects in the internal list to you/as topic for a new question :-D
The downside of this approach: It is not very flexible - adding more states per user involves some coding.
It could be better for you to read about typed datasets and how to store/read them from XML. This gives you some sort of "database feeling" without actually having to use a database.

Winforms preferences values

I'm a beginner in winforms, and just starting using it's preferences.
So, I add in my Settings.settings a Value named path, as string and User Scope.
I change it when I choose a new path with a FolderBrowserDialog and then, after a click on a Ok button, i change the preferences like this :
private void buttonPref_Click(object sender, EventArgs e)
{
Form2 subForm2 = new Form2(textBoxRep.Text);
subForm2.ShowDialog();
if (subForm2.DialogResult == DialogResult.OK)
{
Settings.Default.path= subForm2.rep();
subForm2.Close();
}
else
{
subForm2.Close();
}
}
public string rep()
{
return textBoxRep.Text;
}
Then, when I run my Application, I load the value in my preferences :
textBoxRep.Text = Settings.Default.path;
But, the value is set to empty after every new run.
So I tried with a Application Scope, but I got a read Only error on this : Settings.Default.path
How can I fix this? Is there a way to register the settings after mofified them?
Thank you.
you need to call Save method as below
Settings.Default.path= subForm2.rep();
Settings.Default.Save();
Settings that are application-scoped are read-only, and can only be
changed at design time or by altering the .config file in between
application sessions. Settings that are user-scoped, however, can be
written at run time just as you would change any property value. The
new value persists for the duration of the application session. You
can persist the changes to the settings between application sessions
by calling the Save method.
How To: Write User Settings at Run Time with C#
You need to also call Settings.Default.Save();

Having trouble in using sample code for registry key

The sample code can be found here:
http://msdn.microsoft.com/en-us/library/cc197002(v=vs.85).aspx
The code is about a third of the way down on the page, immediately underneath "Community Content" "IERegCreateKeyEx now working in c#, Please can you help with RegCloseKey"
Thanks for any help. I've tried for several days to use this. It compiles perfectly but I can't manage to call the public SetRegValue and CreatRegKey functions exposed in the public static class ProtectedModeHelper.
Any IE key value can be used in the sample; feel free to use your own in an example, e.g., HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Settings.
Since you are programming in C#, you could use the RegistryKey class to perform such tasks. Below is a sample code from MSDN showing how to create keys and set their values:
static void Main()
{
// Create a subkey named Test9999 under HKEY_CURRENT_USER.
RegistryKey test9999 =
Registry.CurrentUser.CreateSubKey("Test9999");
// Create two subkeys under HKEY_CURRENT_USER\Test9999. The
// keys are disposed when execution exits the using statement.
using(RegistryKey
testName = test9999.CreateSubKey("TestName"),
testSettings = test9999.CreateSubKey("TestSettings"))
{
// Create data for the TestSettings subkey.
testSettings.SetValue("Language", "French");
testSettings.SetValue("Level", "Intermediate");
testSettings.SetValue("ID", 123);
}
}
To modify an existing key you have to open it using the RegistryKey.OpenSubKey Method specifying that you want write access to be applied to the key, then you can call SetValue like showed above.

Observable collection not getting retrieved from isolated storage settings in WP7 app

I am storing the observable collection in my application isolated storage settings. The list is getting saved successfully during the application exit. But when I launch the application again its not able to find the stored key from the isolated storage.
Here is my code
void LoadSettings()
{
if (settings.Contains("DiaryItems"))
{
diaryItems = (ObservableCollection<MyDiaryItem>)settings["DiaryItems"];
}
}
void SaveSettings()
{
settings["DiaryItems"] = diaryItems;
}
I am calling SaveSettings method during my application closing and application deactivated.
I am calling LoadSettings method during my application launching and application activated.
When I was debugging I could see an error saying that
'settings["DiaryItems"]' threw an exception of type
'System.Collections.Generic.KeyNotFoundException'
Just wondering what could be wrong with the settings. The same code works for a simple list of type List.
Actually when you want to store any items in the IsolatedStorage you have to call the save of ApplicationSettings function
so modify your save function as follows,
void SaveSettings()
{
settings["DiaryItems"] = diaryItems;
settings.Save();
}
Sorry i forgot to mention you that , your MyDiaryItem, should be properly serializable.
Note sure why it doesn't work, but you can try to wrap your ObservableCollection inside of a list:
void LoadSettings()
{
if (settings.Contains("DiaryItems"))
{
diaryItems = new ObservableCollection<MyDiaryItem>((List<MyDiaryItem>)settings["DiaryItems"]);
}
}
void SaveSettings()
{
settings["DiaryItems"] = diaryItems.ToList();
}
You need to have using System.Linq; at the top of your file, or the 'ToList' won't work.
try to add your data in dictionary using Add function
like
isolatedstorege.Add(key,value);
this way it adds the value more

Reading default application settings in C#

I have a number of application settings (in user scope) for my custom grid control. Most of them are color settings. I have a form where the user can customize these colors and I want to add a button for reverting to default color settings. How can I read the default settings?
For example:
I have a user setting named CellBackgroundColor in Properties.Settings.
At design time I set the value of CellBackgroundColor to Color.White using the IDE.
User sets CellBackgroundColor to Color.Black in my program.
I save the settings with Properties.Settings.Default.Save().
User clicks on the Restore Default Colors button.
Now, Properties.Settings.Default.CellBackgroundColor returns Color.Black. How do I go back to Color.White?
#ozgur,
Settings.Default.Properties["property"].DefaultValue // initial value from config file
Example:
string foo = Settings.Default.Foo; // Foo = "Foo" by default
Settings.Default.Foo = "Boo";
Settings.Default.Save();
string modifiedValue = Settings.Default.Foo; // modifiedValue = "Boo"
string originalValue = Settings.Default.Properties["Foo"].DefaultValue as string; // originalValue = "Foo"
Reading "Windows 2.0 Forms Programming", I stumbled upon these 2 useful methods that may be of help in this context:
ApplicationSettingsBase.Reload
ApplicationSettingsBase.Reset
From MSDN:
Reload contrasts with Reset in that
the former will load the last set of
saved application settings values,
whereas the latter will load the saved
default values.
So the usage would be:
Properties.Settings.Default.Reset()
Properties.Settings.Default.Reload()
Im not really sure this is necessary, there must be a neater way, otherwise hope someone finds this useful;
public static class SettingsPropertyCollectionExtensions
{
public static T GetDefault<T>(this SettingsPropertyCollection me, string property)
{
string val_string = (string)Settings.Default.Properties[property].DefaultValue;
return (T)Convert.ChangeType(val_string, typeof(T));
}
}
usage;
var setting = Settings.Default.Properties.GetDefault<double>("MySetting");
Properties.Settings.Default.Reset() will reset all settings to their original value.
I've got round this problem by having 2 sets of settings. I use the one that Visual Studio adds by default for the current settings, i.e. Properties.Settings.Default. But I also add another settings file to my project "Project -> Add New Item -> General -> Settings File" and store the actual default values in there, i.e. Properties.DefaultSettings.Default.
I then make sure that I never write to the Properties.DefaultSettings.Default settings, just read from it. Changing everything back to the default values is then just a case of setting the current values back to the default values.
How do I go back to Color.White?
Two ways you can do:
Save a copy of the settings before the user changes it.
Cache the user modified settings and save it to Properties.Settings before the application closes.
I found that calling ApplicationSettingsBase.Reset would have the effect of resetting the settings to their default values, but also saving them at the same time.
The behaviour I wanted was to reset them to default values but not to save them (so that if the user did not like the defaults, until they were saved they could revert them back).
I wrote an extension method that was suitable for my purposes:
using System;
using System.Configuration;
namespace YourApplication.Extensions
{
public static class ExtensionsApplicationSettingsBase
{
public static void LoadDefaults(this ApplicationSettingsBase that)
{
foreach (SettingsProperty settingsProperty in that.Properties)
{
that[settingsProperty.Name] =
Convert.ChangeType(settingsProperty.DefaultValue,
settingsProperty.PropertyType);
}
}
}
}

Categories

Resources