I have this code:
cpMythic0.Text = Properties.Settings.Default.M0;
and let's say I have 31 cpMythic (string) variables all being named "cpMythic0, cpMythic1, cpMythic2 ... cpMythic30 and the same goes with some Properties Settings string variables called "M0,M1,M2...M30"
Instead of writing this:
cpMythic0.Text = Properties.Settings.Default.M0;
cpMythic1.Text = Properties.Settings.Default.M1;
I would like to use a for() function, with an i variable but I don't really know the syntax.
I would appreciate any help.
I'm not sure why you'd want to do this, but this is achievable using reflection.
Here is an example:
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Fill_Click(object sender, EventArgs e)
{
string propertyMatcher = "cpMythic";
var defaultSettings = new Properties.Settings.Default(); //Get instance of default settings
var settingProperties = defaultSettings.GetType().GetFields(); //Get default setting properties.
foreach (TextBox control in this.Controls.OfType<TextBox>().Where(c => c.Name.StartsWith("cpMythic"))) //Loop through controls, and filter
{
string settingPropertyName = "M" + control.Name.Substring(propertyMatcher.Length);
var settingProperty = settingProperties.FirstOrDefault(p => p.Name == settingPropertyName);
var value = settingProperty.GetValue(defaultSettings); //Get the value of the corresponding setting using reflection
control.Text = value.ToString(); //Set value
}
}
private static class Properties
{
public static class Settings
{
public class Default
{
public string M0 = "Default Value 0";
public string M1 = "Default Value 1";
public string M2 = "Default Value 2";
}
}
}
}
}
Related
I am making a program in C# for accessing and storing passwords, as a school project.
I have a text file, passwords.txt, with account names and the associated passwords as such:
gmailUsername:gmailPassword
facebookUsername:facebookPassword
So colon (:) between username and password and new line for new site/account whatever.
In the Windows Form i have a listBox that should get its items (only accounts) from reading the passwords.txt file.
Once a item from the listBox has been selected, a textbox in the same Form should show only that associated password from that same text file.
How can I code this? I am stuck on trying to figure out how to read the file and putting all profile entries into an array, then adding these as list items in the listBox. And putting all passwords into another array.
This code would do the job.
You need to create a form with a ListBox named "listBox1" and a TextBox named "textBox1".
public partial class Form1 : Form
{
List<Account> Accounts = new List<Account>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Accounts.Clear();
foreach (string line in File.ReadAllLines("passwords.txt"))
{
int pos = line.IndexOf(':');
if (pos > 0)
{
Accounts.Add(new Account() { Service = line[0..pos], Password = line[(pos + 1)..] });
}
}
listBox1.DataSource = Accounts;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox1.Text = ((sender as ListBox)?.SelectedItem as Account)?.Password;
}
}
class Account
{
public string Service { get; set; }
public string Password { get; set; }
public override string ToString()
{
return Service;
}
}
Here is what i ended up with. Changed the method slightly. Used List instead of an array.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PSN_PasswordManager
{
public partial class FormVaultUnlocked : Form
{
List<string> myAccounts = new List<string>();
List<string> myPasswords = new List<string>();
string[] passLines;
public FormVaultUnlocked()
{
InitializeComponent();
getProfiles();
}
private void lstProfiles_SelectedIndexChanged(object sender, EventArgs e)
{ // When new list item is chosen
// Gets selected item (string)
string curItem = lstProfiles.SelectedItem.ToString();
//MessageBox.Show(curItem); //testing
string tempPassword = null;
for (int i = 0; i < myAccounts.Count; i++)
{
if (myAccounts[i] == curItem)
{
tempPassword = myPasswords[i];
}
}
txtPassword.Text = tempPassword;
string showPassword = "yeet";
//txtPassword.Text = showPassword;
}
void getProfiles()
{
// Lese tekstfil
string[] passLines = File.ReadLines("passwords.txt").ToArray();
// Legge til items fra array til listBox
foreach (string profile in passLines)
{
// splitting acc. and pass. into strings in new array.
// account[0] is account name. account[1] is password.
string[] accPass = profile.Split(':');
// adds account as list items. And accounts and passwords to global lists.
lstProfiles.Items.Add(accPass[0].ToString());
myAccounts.Add(accPass[0]);
myPasswords.Add(accPass[1]);
}
}
}
}
I need to set a label to zero. It is showing 120. There is a button that will return the required hours for this program. It is a program that returns the required hours for students major. There are 3 forms. bladah bladah yadah yadah. asdfkashdfjkhasjkdhfjkasdjkfajkdjfkajksdfjkakjshdfkjakjsdfjkashdfakjsdf
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Computer_Science_Student
{
class CompSciStudent : Student
{
// Constants
private double MATH_HOURS = 20;
private double CS_HOURS = 40;
private double GEN_HOURS = 60;
// Fields
private string _academicTrack;
// Constructor
public CompSciStudent(string name, string id, string track)
: base(name, id)
{
_academicTrack = track;
}
// AcademicTrack property
public string AcademicTrack
{
get { return _academicTrack; }
set { _academicTrack = value; }
}
// RequiredHours property
public override double RequiredHours
{
get { return MATH_HOURS + CS_HOURS + GEN_HOURS; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Computer_Science_Student
{
abstract class Student
{
// Fields
private string _name;
private string _id;
// Constructor
public Student(string name, string id)
{
_name = name;
_id = id;
}
// Name property
public string Name
{
get { return _name; }
set { _name = value; }
}
// ID property
public string ID
{
get { return _id; }
set { _id = value; }
}
// RequiredHours property (abstract)
public abstract double RequiredHours
{
get;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Computer_Science_Student
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Variables to hold input
string name, id, track;
// Get the student's name and ID.
name = nameTextBox.Text;
id = idTextBox.Text;
// Get the student's academic track
if (infoSystemsRadioButton.Checked)
{
track = "Information Systems";
}
else
{
track = "Software Engineering";
}
// Create a CompSciStudent object.
CompSciStudent csStudent =
new CompSciStudent(name, id, track);
// Display the student's required hous.
requiredHoursLabel.Text =
csStudent.RequiredHours.ToString("n1");
}
private void ExitButton_Click(object sender, EventArgs e)
{
// Close the form
this.Close();
}
}
}
In your code class CompSciStudent has the following attributes and methods:
// Constants
private double MATH_HOURS = 20;
private double CS_HOURS = 40;
private double GEN_HOURS = 60;
public override double RequiredHours
{
get { return MATH_HOURS + CS_HOURS + GEN_HOURS; }
}
RequiredHours always returns sum of MATH_HOURS + CS_HOURS + GEN_HOURS, which equals 120.
Also as another person pointed out, those are not constants, they are variables. A constant would be:
const double MATH_HOURS = 20;
Here you're creating a new CompSciStudent object:
// Create a CompSciStudent object.
CompSciStudent csStudent = new CompSciStudent(name, id, track);
// Display the student's required hous.
requiredHoursLabel.Text = csStudent.RequiredHours.ToString("n1");
In your Form1_Load() method you're setting requiredHoursLabel.Text to csStudent.RequiredHours which is always 120 that's why you're seeing "120" in the text field.
The Form1_Load() method is going to be called after your form loads so it is typically used to initialize the form. So what you're doing right now is to initialize requiredHoursLabel.Text to 120.
If you have some other behavior in mind they you'll need to add something like another button besides "Close" like "OK" or "Save" or something to accept the input the user entered into the form.
Backstory: I am creating (trying) a inventory management application for android. For data replication testing I made simple WinForms application. Purpose of this app is simply to load data from SQL Server DB (DB table name is T_STOCK). For data manipulation I used Linq and for loading I used DataGridView and for app architecture I am trying to use MVP.
Problem: I am having a hard time to fill DataGrid with data. I already tried to pass hole datagrid as a property and now just a data source. Am I missing something or it should be done in a different way?
This is part of the code that is in my project:
Model:
using System;
using System.Linq;
using System.Configuration;
using InventoryManagment.Services.DE.SQLServer;
using System.Windows.Forms;
namespace InventoryManagment.Models
{
public class Stock
{
private string _ConnectionString;
object _DgView;
public object DataGridViewItems { get; set; }
DEDataContext oDB;
BindingSource bindingSource;
DataGridView dataGridView;
public void GetStockAllRecords()
{
_ConnectionString = ConfigurationManager.
ConnectionStrings["SimpleInventoryManagment_temp." +
"Properties.Settings.dbInventoryMngConnectionString"].ToString();
oDB = new Services.DE.SQLServer.DEDataContext(_ConnectionString);
//int count = (from row in oDB.T_STOCKs select row).Count();
bindingSource = new BindingSource();
dataGridView = new DataGridView();
var stock = from t_stock in oDB.T_STOCKs
select new
{
ID = t_stock.F_ID,
Name = t_stock.F_NAME,
Barcode = t_stock.F_BARCODE
};
bindingSource.DataSource = stock;
dataGridView.DataSource = bindingSource;
_DgView = dataGridView.DataSource;
}
}
}
View:
using System;
namespace InventoryManagment.Views
{
public interface IStock
{
object DataGridViewItems { get; set; }
}
}
Presenter:
using System;
using System.Linq;
using InventoryManagment;
using System.Windows.Forms;
namespace InventoryManagment.Presenters
{
public class StockPresenter
{
Views.IStock StockView;
Models.Stock stock = new Models.Stock();
public StockPresenter(Views.IStock view) { StockView = view; }
public void GetStockAllRecords()
{
stock.GetStockAllRecords();
StockView.DataGridViewItems = stock.DataGridViewItems;
}
}
}
Form
using System;
using System.Windows.Forms;
using InventoryManagment;
namespace InventoryManagment
{
public partial class FormMain : Form, Views.IStock
{
string BtnAddMsgBoxText;
public FormMain()
{
InitializeComponent();
}
object Views.IStock.DataGridViewItems
{
get
{
return GrItems.DataSource;
}
set
{
GrItems.DataSource = value;
}
}
private void FormMain_Load(object sender, EventArgs e)
{
Presenters.StockPresenter presenter =
new Presenters.StockPresenter(this);
presenter.GetStockAllRecords();
}
}
}
Well I think I was thinking to hard. #Reza Aghaei was right.
public void GetStockAllRecords()
{
_ConnectionString = ConfigurationManager.
ConnectionStrings["SimpleInventoryManagment_temp." +
"Properties.Settings.dbInventoryMngConnectionString"].ToString();
oDB = new Services.DE.SQLServer.DEDataContext(_ConnectionString);
var stock = from t_stock in oDB.T_STOCKs
select new
{
ID = t_stock.F_ID,
Name = t_stock.F_NAME,
Barcode = t_stock.F_BARCODE
};
DataGridViewItems = stock;
}
I have a routine which opens a recordset and builds the Items collection for a combo box. After googling around I found the approach which uses the ComboboxItem class.
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Display;
}
}
My code uses this class to Add items to the ComboBox. When I run the app and click the Combobox the correct values are in the list... great! My problem is that when the form loads a record from the database, instead it looking up the appropriate list value which corresponds to the database value, it simply shows the value from the database: eg UK instead of United Kingdom. When I try to save the record, it tries to save "United Kingdom" instead of "UK". So I think the DisplayMember and ValueMember properties need assigning. I assumed that I would need to assign them as "Text" and "Value", but when I do this the Combobox displays a list of identical values. What am I doing wrong please?
Edit: This is a simplified version of what I have put into my ComboBox Class:
public class StandardComboBox : ComboBox
{
protected List<ComboboxItem> DataSourceList = new List<ComboboxItem>();
public bool SetRecordSource(string Criteria)
{
ADODB.Recordset RS = new ADODB.Recordset();
try
{
DataSourceList.Clear();
// Open ADDOB.Recordset RS with the records specified in Criteria
while (RS.EOF == false)
{
ComboboxItem MyComboboxItem = new ComboboxItem();
MyComboboxItem.Value = RS.Fields[0].Value.ToString();
MyComboboxItem.Display = RS.Fields[1].Value.ToString();
DataSourceList.Add(MyComboboxItem);
RS.MoveNext();
}
this.DataSource = DataSourceList;
this.ValueMember = "Value";
this.DisplayMember = "Display";
return true;
}
}
}
First, I think you should name your class better (eg. Country). Then set the name of the property too. Use string as your data type.
public class Country
{
public string ID { get; set; }
public string Name { get; set; }
}
Then you bind the combobox and set the DisplayMember and DisplayValue.
comboBox1.DataSource = listCountry;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
If you want to take the value, just use SelectedValue.
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(comboBox1.SelectedValue.ToString());
}
Full source code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var listCountry = new List<Country>() {
new Country() {ID = "UK", Name = "United Kingdom"},
new Country() {ID = "US", Name = "United States of America"},
};
comboBox1.DataSource = listCountry;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(comboBox1.SelectedValue.ToString());
}
}
public class Country
{
public string ID { get; set; }
public string Name { get; set; }
}
}
I've managed to work this out now. I'm from an MsAccess background where for example you just assign a combobox with 'UK' and the combobox displays 'United Kingdom'. In C# it's more complicated. When you want to assign a combobox with a value, you have to use the FindString() method to locate the value you want to display, then assign the SelectedIndex property in order to make it display that value. It's a ball ache, but I can build this logic into my class and not have to think about it again. Thanks for your input. –
For my windows forms application I tried to retrieve the selected string from a listBox and i wanted it to compare to a set string so that, in the event of the comparison returning true, i can set the next listBox to have specific, selection-related values.
namespace PhysCalc
{
public class Selectors
{
public static string[] topicContents = new string[] { "MECHANICS", "THEORY_OF_RELATIVITY" };
public static string[] VarItemsMechanics = new string[] { "Test", "Wavelength" };
public static void SetVarBox()
{
PhysCalc.Topic.DataSource = topicContents;
if PhysCalc.Topic.Items[PhysCalc.Topic.SelectedIndex].ToString() == "MECHANICS")
{
PhysCalc.Var.DataSource = VarItemsMechanics;
}
}
}
}
But somehow when i select "MECHANICS" in the listBox(in the code above named 'Topic'), the 2nd listBox(above named 'Var') just stays empty
any help would be very appreciated
I think you need to set the DisplayMember and ValueMember properties on the Var list control when using the DataSource.
If the DataSource is an object then DisplayMember is the object member it will use as the text display (which in your case is currently blank), and ValueMember is used to determine the SelectedValue property of the list control which is useful to bind against.
For example if your VarItemsMechanics is populated with the following class:
public class Mechanic
{
public int ID { get; set; }
public string Name { get; set; }
}
Then you probably want to set the DisplayMember to "Name" and you might want to set the ValueMember to "ID" (subjective).
Try changing
if (PhysCalc.Topic.GetItemText(PhysCalc.Topic.SelectedItem) == "MECHANICS")
to this:
if (PhysCalc.Topic.Items[PhysCalc.Topic.SelectedIndex].ToString() == "MECHANICS")
1- Bind your First List named "Topic" in the form_load Event
2- in the SelectedIndexChanged Event of your First List do your checks about the selected Item
and Fill the Second List
Here is the Complete Code and it works fine for me
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string[] topicContents = new string[] { "MECHANICS", "THEORY_OF_RELATIVITY" };
public static string[] VarItemsMechanics = new string[] { "Test", "Wavelength" };
private void Form1_Load(object sender, EventArgs e)
{
listBox1.DataSource = topicContents;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string curItem = listBox1.SelectedItem.ToString();
switch (curItem)
{
case "MECHANICS":
listBox2.DataSource = VarItemsMechanics;
break;
}
}
}
}