I have created two settings file under properties in c#. Basically I have to apply settings based on a particular set of condition
for example the settings file are "myset1" and "myset2"
both these settings have similar structure
myset1
price = 100
qty = 100
myset2
price = 150
qty = 20
in my application, if value of variable "appColor" is "blue" myset1 has to be used if variable "appColor" is "red" myset2 has to be used.
in my code
productPrice.Text = //based on the "appColor" selection value from myset1 or myset2 has to be displayed.
I tried this but not working
Settings setSelector = new Settings();
if(appColor == "blue")
{
setSelector = myset1.Default;
}
else(appColor == "red")
{
setSelector = myset2.Default;
}
I am getting error that "cannot convert source type "myset1" to settings"
EDIT: my aim is that productPrice.Text = setSelector.Price; remains same even when settings are changed so I don't have to change code here and just have to change the settings. basically full forms gets filled based on the settings selected.
any help would be appreciated
I tried below code. it worked correctly.
I have two Textboxes, in which i am setting Price and Qty based on color.
Object obj = new Object();
if(appColor == "blue")
{
obj = (System.Configuration.SettingsPropertyCollection)Properties.Settings.Default.Properties;
}
else(appColor == "red")
{
obj = (System.Configuration.SettingsPropertyCollection)Properties.Settings1.Default.Properties;
}
foreach (System.Configuration.SettingsProperty p in Properties.Settings.Default.Properties)
{
if (p.Name=="Qty")
textBox1.Text = p.DefaultValue.ToString();
else if (p.Name=="Price")
textBox2.Text = p.DefaultValue.ToString();
}
I Hope this helps :)
After playing around with it a bit and referencing this MSDN article specifically the last section on adding alternate sets of settings.
To Add an Additional Set of Settings
From the Project menu, choose Add New Item. The Add New Item dialog box opens.
In the Add New Item dialog box, select Settings File.
In the Name box, give the settings file a name, such as SpecialSettings.settings, and click Add to add the file to your
solution.
In Solution Explorer, drag the new settings file into the Properties folder. This allows your new settings to be available in
code.
Add and use settings in this file as you would any other settings file. You can access this group of settings through the
Properties.SpecialSettings object.
I then realized that each settings file is its own separate class therefore you have to go back to a common class. By doing so you will loose your individual properties and have to cast it to the proper class. I then looked at this SO question searching for dynamic casting. According to JaredPar's answer it appears that the easiest way to do this would be to use the dynamic keyword and let the class type be figured out at runtime.
i.e.
Class level Declaration:
dynamic setSelector;
Intializing it during Form Load:
private void Form1_Load(object sender, EventArgs e)
{
if(appColor == "blue")
{
setSelector = Properties.myset1.Default;
}
else if(appColor == "red")
{
setSelector = Properties.myset2.Default;
}
textBox1.Text = setSelector.qty.ToString();
}
Related
hey guys i wanna to load a File path in my listBox.
everything is ok
i just have a problem that is when i Close the app and then open it again
loaded files are in the one lane and it recognize them as one item in listBox
i tried to use "\n" , "\r" none of these works...
so what u guys suggest?
(i save user changes in App Setting to read them later)
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default.FileList != string.Empty)
{
fileListBox.Items.Add(Properties.Settings.Default.FileList);
}
UnlockForm f2 = new UnlockForm();
if (Properties.Settings.Default.PasswordCheck == true)
f2.ShowDialog();
else
return;
}
private void button1_Click_1(object sender, EventArgs e)
{
op = new OpenFileDialog();
op.Title = "Select your stuff";
op.Filter = "All files (*.*)|*.*";
if (op.ShowDialog() == DialogResult.OK)
{
fileName = op.FileName;
fileListBox.Items.Add(fileName);
}
Properties.Settings.Default.FileList += fileName+"\n";
Properties.Settings.Default.Save();
}
When creating the property in settings designer:
Set the name to whatever you want, for example Files
Set the type as System.Collections.Specialized.StringCollection
Set the scope as User
If you want to have some default values, use ... in Value cell to edit default value.
Then you can easily set it as DataSource of the ListBox.
listBox1.DataSource = Properties.Settings.Default.Files;
Also to add some values:
Properties.Settings.Default.Files.Add("something");
Properties.Settings.Default.Save();
If you added something to the Files, if you want the ListBox shows the changes, set DataSource to null and then to Files again.
It looks like you have defined your FileList as String in our App Settings. There are two ways you can approach this.
a) Using FileList as Collection.
You can change the Type of FileList to StringCollection in your App Settings. Then, you can add items to your list as follows
fileListBox.Items.AddRange(Properties.Settings.Default.FileList.Cast<string>().ToArray());
b) Using FileList as String.
If you really want to retain Properties.Settings.Default.FileList as string, you would need to split it on the run using your delimiter character (let's say ';')
fileListBox.Items.AddRange(Properties.Settings.Default.FileList.Split(new[] { ';' },StringSplitOptions.RemoveEmptyEntries));
In your case, a collection might be a better approach unless you have specific reasons outside the scope of OP to use string.
I have a simple list, like this:
fruitList = new FruitList();
Apple fruit1 = new Apple("red", "small");
Banana fruit2 = new Banana("yellow", "big");
fruitList.AddFruit(fruit1);
fruitList.AddFruit(fruit2);
My program displays this in a Textbox:
textbox.Text = fruitList.DescribeCurrentFruit()
+
public string DescribeCurrentFruit()
{
string description;
if (fruitStock.Count > 0)
{
description = fruitStock[fruitCurrentlyDisplayed].Description();
}
else
{
description = "No Fruits in stock";
}
return description;
}
Currently, the List's two current objects/items (fruit1, fruit2) are automatically loaded as they are a part of my Window Form's load_event. However, if they're not a part of the load_event, or if I want to add more items/objects to the list at runtime, then permanently save them, how can I do so?
Well, I can do so by saving items in the project's property settings. (Serialization is an alternative option, but far too complex for me, and I want the simplest solution.) How do I go about this? Is there any sample code? I understand I first need to add items into my properties, but struggle even at this step.
So, I have Form called Preferences with TabControl in it. This TabControl contains several TabPages(General, Advanced, Misc, ...) with few comboboxes, checkboxes and labels. Each of this control inside TabPage is assigned Application Settings Property Binding (aka they show saved user settings, user can change them etc...).
I know that there is a method to reset all settings (Properties.Settings.Default.Reset();), but is there a way how to reset only settings inside one TabPage?
My solution is to iterate thru controls in TabPage, check if it is combobox, label etc and then reset it´s value to default, but is there a "oneliner" solution to this ?
Use the following solution to get the original value of a single setting:
(The example assumes you want to get the ORIGINAL value of a setting named 'Username')
var defaultUsername = Properties.Settings.Default.GetType()
.GetProperty(nameof(Properties.Settings.Default.Username))
.GetCustomAttribute<System.Configuration.DefaultSettingValueAttribute>()
.Value;
Important - this solution will always return a string value. make sure to parse it properly, or use this extension method I wrote:
public static T GetDefaultValue<T>(this ApplicationSettingsBase settings, string settingKey)
{
return (T)Convert.ChangeType(settings.GetType()
.GetProperty(settingsKey)
.GetCustomAttribute<DefaultSettingValueAttribute>()
.Value, typeof(T));
}
Usage:
var defaultNumber = Properties.Settings.Default.GetDefaultValue<int>(nameof(Properties.Settings.Default.Number));
The ApplicationSettings doesn't have built-in support to reset just some properties. But to solve the problem, you can use either of these options:
Create a method which resets all bound controls of a TabPage
Using Multiple Settings Files with Designer Support
Option 1 - Create a method which resets all bound controls of a TabPage
You can create a method which look at controls of the tab page and check if it's bound to application settings, find the property in settings and reset its value to the default value. Then you can reset settings of a TebPage width one line of code: ResetSettings(tabPage1);.
Here is the method:
private void ResetSettings(TabPage tabPage)
{
foreach (Control c in tabPage.Controls)
{
foreach (Binding b in c.DataBindings)
{
if (b.DataSource is ApplicationSettingsBase)
{
var settings = (ApplicationSettingsBase)b.DataSource;
var key = b.BindingMemberInfo.BindingField;
var property = settings.Properties[key];
var defaultValue = property.DefaultValue;
var type = property.PropertyType;
var value = TypeDescriptor.GetConverter(type).ConvertFrom(defaultValue);
settings[key] = value;
//You can also save settings
settings.Save();
}
}
}
}
Option 2 - Using Multiple Settings Files with Designer Support
If the reason of using a single settings file is because of designer support, you should know you can have designer support also with multiple settings files. Then you can use different settings files and reset each settings group separately. You can simply encapsulate them in a single class using such code:
public static class MySettings
{
public static Sample.General General
{
get { return Sample.General.Default; }
}
public static Sample.Advanced Advanced
{
get { return Sample.Advanced.Default; }
}
public static void ResetAll()
{
General.Reset();
Advanced.Reset();
}
public static void SaveAll()
{
General.Save();
Advanced.Save();
}
}
To reset a setting group it's enough to call MySettings.General.Reset();
To reset all settings, you can call MySettings.ResetAll();
Note for design-time support
To have designer support for binding properties to settings, create multiple settings files in root of your project. Don't put settings files in folders. The setting picker, only shows Settings.settings file which is in Properties folder and those files which are in root of project. This way you can see different settings files and settings properties in a tree-view like this:
TabPage page = aTabControl.SelectedTab;
var controls = page.Controls;
foreach (var control in controls)
{
//do stuff
}
Try this:
private void button2_Click(object sender, EventArgs e)
{
TabPage page = tabControl1.SelectedTab;
var controls = page.Controls;
foreach (var control in controls)
{
if(control is TextBox)
{
//do stuff
}
if(control is ComboBox )
{
ComboBox comboBox = (ComboBox)control;
if (comboBox.Items.Count > 0)
comboBox.SelectedIndex = 0;
comboBox.Text = string.Empty;
}
}
}
I've got a Picturebox, the user can select its backgroundimage out of a resource file.
Later I want to get the resourcename out of the picturebox.
I've already tried this:
MessageBox.Show(((PictureBox)sender).BackgroundImage.ToString());
But it gave me the format of the picture.. there isnt something like:
MessageBox.Show(((PictureBox)sender).BackgroundImage.Name.ToString());
and I've already thougt about setting a Tag to the Picturebox with the picturename when setting the Image... but this is annoying as hell...
So how can I get the name of the Resource used as the backgroundimage at a Picturebox easily?
I think i have to explain the whole situation:
Ive got a form with a lot of raidbuttons...
if you select one of those buttons and click on a panel,the panel changes to the selected radiobuttonimage...
the click event of the panel:
PanelClick(object obj ,...)
{
if(radiobuttonApple.checked)
{
obj.backgroundimage = resource.apple;
}
if(radiobuttonPear.checked)
{
obj.backgroundimage = resource.Pear;
}
}
and hundred more of those...
and later on i want to know wich resourcefile the backgroundimage is..
Isnt there something like this:
(if i would name the radiobuttons like the resources)
PanelClick(object obj ,...)
{
obj.backgroundimage = resource[selectedradiobutton.Name]
obj.tag = selectedradiobutton.Name
}
So now im about to use LINQ:
RadioButton checkedRadioButton = panel1.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked);
obj.tag = checkedRadioButton.Text;
so i only need to know how to get a resource dinamical by name e.g.:
obj.backgroundimage = resource[checkedRadioButton.Text];
and ill use a resourcemanager :
var resman = new System.Resources.ResourceManager(
"RootNamespace.Pictures",
System.Reflection.Assembly.GetExecutingAssembly()
)
var image = resman.GetPicture("checkedRadioButton.Text");
i hope this will work ..
Create a method to return the resource based on the selected radio button.
Example:
private resource checkResource()
{
if(radiobuttonApple.checked)
{
return resource.apple;
}
if(radiobuttonPear.checked)
{
return resource.Pear;
}
}
Then you can use it like this:
PanelClick(object obj ,...)
{
obj.backgroundimage = checkResource();
}
or
PanelClick(object obj ,...)
{
obj.backgroundimage = checkResource();
obj.tag = selectedradiobutton.Name
}
EDIT:
As you said, this approach can have different problems based on the number of iterations for each assignment. To avoid this and also in the light of another solution, you can use a single event to handle all the radio button state changes like this:
First, create a resource variable to be assigned to whenever a radioButton's status changes. ie.
private Resource bgResource;
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton obj = sender as RadioButton;
bgResource = resman.GetPicture(obj.Tag);
}
Then any time you want to change background you can simply say:
obj.BackgroundImage = bgResource;
I wrote this to quickly test
Why arent my settings being saved? The first time i run this i have 3(old)/3(current) elements. The second time i get 3(old)/5(current), third time 5(old)/5(current).
When i close the app the settings completely disappear. Its 3 again when i run it. I made no changes to the app. Why arent my settings being saved
private void button2_Click(object sender, EventArgs e)
{
MyApp.Properties.Settings.Default.Reload();
var saveDataold = MyApp.Properties.Settings.Default.Context;
var saveData = MyApp.Properties.Settings.Default.Context;
saveData["user"] = textBox1.Text;
saveData["pass"] = textBox2.Text;
MyApp.Properties.Settings.Default.Save();
}
You should be using the exposed properties instead of putting your data in the context:
var saveData = MyApp.Properties.Settings.Default;
saveData.user = textBox1.Text;
saveData.pass = textBox2.Text;
The context
provides contextual information that
the provider can use when persisting
settings
and is in my understanding not used to store the actual setting values.
Update: if you don't want to use the Settings editor in Visual Studio to generate the strong-typed properties you can code it yourself. The code generated by VS have a structure like this:
[UserScopedSetting]
[DebuggerNonUserCode]
[DefaultSettingValue("")]
public string SettingName
{
get { return ((string)(this["SettingName"])); }
set { this["SettingName"] = value; }
}
You can easily add more properties by editing the Settings.Designer.cs file.
If you don't want to use the strong-typed properties you can use the this[name] indexer directly. Then your example will look like this:
var saveData = MyApp.Properties.Settings.Default;
saveData["user"] = textBox1.Text;
saveData["pass"] = textBox2.Text;