How can I pass data between windows in my C# WPF application? - c#

I have a login form in the MainWindow of my WPF application. If the user logs in successfully, I want to open the HomeWindow. My problem is that I need to pass the adminID variable from the MainWindow to the HomeWindow. How can I do this?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
int errors = 0;
if (txtUsername.Text == "")
{
lblUsernameStatus.Content = "This field is required.";
errors = errors + 1;
}
if (txtPassword.Text == "")
{
lblPasswordStatus.Content = "This field is required.";
errors = errors + 1;
}
if (errors == 0)
{
Administrator TryLogin = new Administrator();
if (TryLogin.VerifyUser(txtUsername.Text, txtPassword.Text))
{
HomeWindow home = new HomeWindow();
int adminID = TryLogin.userID;
home.Show();
this.Close();
}
else
{
lblLoginStatus.Content = TryLogin.status;
}
}
}
PS: I haven't written anything in the HomeWindow.xaml.cs file.

Define an initializer in HomeWindow to accept the data you wish to send:
private int AdminID;
public HomeWindow()
{
InitializeComponent();
}
public HomeWindow(int adminID) : base()
{
AdminID = adminID;
}
Then you can just:
HomeWindow home = new HomeWindow(TryLogin.userID);
home.Show();
this.Close();

Declaring static variable would be the simplest and easiest way because once login is authorized, the value doesn't change until logged off(application is exited)
I also used a way of passing value through Window constructor but static variables are much easier to utilize many fixed data of the logged-in users like customized setting data for each users. I also have a WPF app and pass 11 values and utilize easiily everywhere inside application.
Declare as static variable in MainWindow like,
public static int adminID;
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
adminID= TryLogin.userID;
}
And usage in HomeWindow is like,
MainWindow.adminID
Hope this helps..

There are different ways to achieve this.
Here is an example using singleton
public class User
{
private static readonly User _instance;
private static object syncRoot = new Object();
public string Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string SomeOtherProperty { get; set; }
private User()
{
// Initialize defaults
}
public void Reset()
{
// Clear existing values
}
public static User Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (_instance == null)
_instance = new User();
return _instance;
}
}
}
}
}
On your login form:
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
int errors = 0;
if (txtUsername.Text == "")
{
lblUsernameStatus.Content = "This field is required.";
errors = errors + 1;
}
if (txtPassword.Text == "")
{
lblPasswordStatus.Content = "This field is required.";
errors = errors + 1;
}
if (errors == 0)
{
Administrator TryLogin = new Administrator();
if (TryLogin.VerifyUser(txtUsername.Text, txtPassword.Text))
{
User.Instance.Reset(); // Make sure old data is removed
User.Instance.Username = txtUsername.Text;
User.Instance.Password = txtPassword.Text;
HomeWindow home = new HomeWindow();
int adminID = TryLogin.userID;
home.Show();
this.Close();
}
else
{
lblLoginStatus.Content = TryLogin.status;
}
}
}
On your home form:
You can retrieve the User credentials using User.Instance just make sure you reset it on logoff.

Related

How do I reference a variable from one class to another?

I'm new to C# and I can't figure out how to reference the value of a variable from one class to another.
It's set to when the button is pressed, it'll take the text in the text box and sets that as "alphaask". Then it instances "alphaanswer" which would tell the label to change its text.
"alphaanswer" will take the value "alphaQuest" and see if its equal to "bob" which then would change the label.
ALL I want to know how to set the value of "alphaQuest" from the value of "alphaask" so the string can check it with "alphaanswer"
public partial class QuestionTab : Form
{
public string alphaask = "null";
public void button1_Click(object sender, EventArgs e)
{
// alphabutton
// Checks if something is in textbox then says bool is true
bool asked = false;
if(textBoxAlpha.Text != "")
{
alphaask = textBoxAlpha.Text;
asked = true;
}
if(asked==true)
{
// If bool is true than instance auxy
var instance = new Alpha();
instance.alphaanswer();
}
}
}
public class Alpha
{
string alphaQuest = // <-- I want to make alphaQuest equal to alphaask
alphaanswer();
public void alphaanswer()
{
if (alphaanswer == bob)
{
//change text in label1
}
}
}
Do these changes
public partial class QuestionTab : Form
{
public string alphaask = "null";
public void button1_Click(object sender, EventArgs e)
{
bool asked = false;
if(textBoxAlpha.Text != "")
{
alphaask = textBoxAlpha.Text;
asked = true;
}
if(asked==true)
{
// If bool is true than instance auxy
var instance = new Alpha();
instance.alphaAnswer(alphaask);
//Here you are sending the current value of alphaAsk to the alphaanswer method.
}
}
}
public class Alpha
{
public void alphaAnswer(string alphaAnswer) //This string receives the value you sent
{
if (alphaAnswer == "bob")
{
//change text in label1
}
}
}
make a contractor in class Alpha with String parameter
public Alpha(String value)
{
}
then when you call it
var instance = new Alpha(alphaask);
instance.show();

How to manage user session in win forms?

I have tried to manage user session, but the issue is I can not access other attributes in the database as they are not in the object.
Teacher t = new Teacher
{
t_email = textBox_Login_Email.Text,
t_password = textBox_Login_Pass.Text,
};
Other attributes are t_id and t_name. I can only access these two using the following code
session.Instance.user.t_email
session.Instance.user.t_password
I need to get Teacher's id which is t_id from the database.
I am storing the object "t" in the session object using
session.Instance.user = t;
Below is the code for my session class and login class
session.cs
public class session
{
#region Define as Singleton
private static session _Instance;
public static session Instance
{
get
{
if(_Instance == null)
{
_Instance = new session();
}
return (_Instance);
}
}
private session()
{
}
#endregion
public Teacher user { get; set; }
public bool isLoggedIn
{
get
{
if (user != null)
return true;
else return false;
}
}
}
login.cs
namespace TestBoardAdmin
{
public partial class Login : Form
{
public Login()
{
InitializeComponent();
}
private void button_Login_Click(object sender, EventArgs e)
{
using (examEntities obj = new examEntities())
{
Teacher t = new Teacher
{
t_email = textBox_Login_Email.Text,
t_password = textBox_Login_Pass.Text,
};
//var x = obj.Teachers.Where(a => a.t_email == t.t_email).Select(a => new { a.t_id });
var y = obj.Teachers.Where(a => a.t_email == t.t_email && a.t_password == t.t_password);
if (y.Count() > 0)
{
MessageBox.Show("Logged In succesfully");
textBox_Login_Email.Clear();
textBox_Login_Pass.Clear();
//this.Close();
session.Instance.user = t;
Chose_Action chose_action = new Chose_Action();
chose_action.Show();
//return 1;
}
else
{
//ViewBag.SuccessMessage = "Wrong Email or Password";
//return 0;
MessageBox.Show("Email or Password Incorrect");
//textBox_Login_Email.Clear();
textBox_Login_Pass.Clear();
}
}
}
private void textBox_Login_Email_TextChanged(object sender, EventArgs e)
{
}
private void textBox_Login_Pass_TextChanged(object sender, EventArgs e)
{
}
}
}
I actually want to store the corresponding t_id in another table when the user adds in the database, the database will also add the id of the user who added something in the database. So, for that I want to get t_id of the corresponding user session.
I have used ado.net and Linq in this project.

Data from form1 listbox to form2 textbox

The goal of the program assignment I'm working on requires me to fill a listbox with items taken from a data file, and then allowing the user to modify parts of the selected item. To do this, I need assistance in figuring out how to pass part of a listbox's selected item in one form to a textbox in another form.
Here's the coding I have for the first form in my program:
public partial class Form1 : Form
{
const char DELIM = '\\';
const string FILENAME = #"C:\Visual Studio 2015\Data Files\Training Workshops data";
string recordIn;
string[] Fields;
static FileStream file = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(file);
public int X;
public Form1()
{
InitializeComponent();
}
public class Workshop
{
public string title { get; set; }
public int days { get; set; }
public string categrory { get; set; }
public double cost { get; set; }
public string[] categrorynames =
{
"Application Development",
"Databases",
"Networking",
"System Administration"
};
}
Workshop shop = new Workshop();
private void button1_Click(object sender, EventArgs e)
{
Form2 secondForm = new Form2();
secondForm.Show();
}
private void PopulateList(string filePath)
{
while(recordIn != null)
{
try
{
recordIn = reader.ReadLine();
Fields = recordIn.Split(DELIM);
X = Convert.ToInt32(Fields[0]);
shop.categrory = shop.categrorynames[X];
shop.days = Convert.ToInt32(Fields[1]);
shop.title = Fields[3];
shop.cost = Convert.ToDouble(Fields[2]);
}
catch (Exception A)
{
if (X < 0 && X > 3)
{
shop.categrory = "invalid";
}
if (shop.days != Convert.ToInt32(Fields[1]))
{
shop.days = 0;
}
if (shop.title != Fields[3])
{
shop.title = "invalid";
}
if (shop.cost != Convert.ToDouble(Fields[2]))
{
shop.cost = 0;
}
}
}
}
}
And below is a link to a screenshot of the second form:
http://i.stack.imgur.com/IRqVh.png
I need to transfer the shop.categrory data of form1's listbox's selected item to the second form's, and the shop.title, shop.days and shop.cost to the corresponding textbox's. From there I can make it so that whatever the user enters in the textboxes would change the data of the selected item when they press the "save and exit" button.
Any help would be appreciated, and if anyone notices an error in the coding I have now, please feel free to point them out.
Create a Parameterized constructor in form2 that accepts a String, and create it's instance in first form, and pass the value you want to pass to the second form:
private void button1_Click(object sender, EventArgs e)
{
Form2 secondForm = new Form2("DATA TO BE SENT");
secondForm.Show();
}
and in form2 Create a Constructor:
public Form2(string data)
{
InitializeComponent();
txtData.Text=data;
}

Multiple windows with the same functionalities

So i was wondering how i would make some kind of superwindow/superclass for my windows. The windows look the following:
The first picture shows how every single one of the windows would potentially look when pressed on one of the buttons. So each of these windows would have the same basic functionality but with some different returning objects which can be seen in the following code.
public partial class FlatsteelWindow : Window {
private string str;
private IList test;
public FlatSteel _returnObject { get; set; }
public double amount { get; set; }
public FlatsteelWindow(object inputObject) {
InitializeComponent();
_returnObject = inputObject as FlatSteel;
FetchList();
}
private void FetchList() {
test = MaterialLogic.GetFlatsteelList() as List<FlatSteel>;
foreach (FlatSteel flatSteel in test) {
flatsteelListView.Items.Add(flatSteel.Name);
}
}
private void flatsteelListView_PreviewMouseLeftButtonUp(object sender, RoutedEventArgs e) {
var item = (sender as ListView).SelectedItem;
if (item != null) {
_returnObject = flatsteelListView.SelectedItems as FlatSteel;
str = item.ToString();
amountTextbox.IsEnabled = true;
FindObject(str);
}
}
private void FindObject(string s) {
foreach (FlatSteel flatSteel in test) {
if (s.Equals(flatSteel.Name)) {
_returnObject = flatSteel;
}
}
}
private void submitButton_Click(object sender, RoutedEventArgs e) {
if (!string.IsNullOrEmpty(amountTextbox.Text)) {
amount = amountTextbox.Text.customParseToDouble();
this.Close();
}
else {
MessageBox.Show("Indtast venligst en værdi.");
}
}
}
This is the code for the shown Flatsteel window.
Here is the code which creates the window:
private void flatsteelButton_Click(object sender, RoutedEventArgs e) {
FlatsteelWindow flatsteelWindow = new FlatsteelWindow(this);
flatsteelWindow.ShowDialog();
test = flatsteelWindow._returnObject;
amount = flatsteelWindow.amount;
if (test != null && amount != null) {
AddToGridView();
}
}
public FlatSteel test { get; set; }
private double amount { get; set; }
As we can see in this code the flatsteel object is needed where this method is invoked. The 6 different windows, which each are represented by the six buttons on the 2nd picture, each return an object to their type of material. So to make it clear what my question is:
How do i make one superclass/superwindow that has all the same basic funtionality, from which i then can inherit from and add the needed functionality for the different returning objects?

ListBox does not update entries automaticly when using binding

Im having some trouble updating a listbox when new data is added to it. This is my code
The my listbox has
<ListBox Name="EmailList" ItemsSource="{Binding ListBoxData, Mode=TwoWay}"
And here is my program:
public partial class MainWindow : Window
{
string hostname = Properties.Settings.Default.pop_host;
int port = Properties.Settings.Default.pop_port;
bool useSsl = Properties.Settings.Default.pop_usessl;
string username = "recent:" + Properties.Settings.Default.username;
string password = Properties.Settings.Default.password;
// When this button is pressed the program starts a backgroundworker
// that begins the download of mails
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker getNewMail = new BackgroundWorker();
getNewMail.DoWork += newEmail;
getNewMail.RunWorkerAsync();
getNewMail.RunWorkerCompleted += updateList;
}
// The actual function that downloads the mails (Using OpenPOP)
private void newEmail(object sender, DoWorkEventArgs e)
{
List<Message> allEmail = FetchAllMessages(hostname, port, useSsl, username, password);
ListBoxData = new List<EmailEntry> { };
foreach (Message singleEmail in allEmail)
{
var mailData = new ListBoxDataClass { theMessage = singleEmail, truncate = 40 };
readyUpListBoxData(mailData);
ListBoxData.Add(new EmailEntry { from = mailData.displayName, subject = mailData.partOfBody, messageID = singleEmail.Headers.MessageId.ToString() });
}
}
public class ListBoxDataClass
{
public Message theMessage { get; set; }
public int truncate { get; set; }
public string partOfBody { get; set; }
public string displayName { get; set; }
}
// A function that does different things with the downloaded data
public void readyUpListBoxData(ListBoxDataClass data)
{
MessagePart theEmailTxt = data.theMessage.FindFirstPlainTextVersion();
string noLineBreaks = theEmailTxt.GetBodyAsText().ToString().Replace(System.Environment.NewLine, " ");
data.partOfBody = noLineBreaks.Length <= data.truncate ? noLineBreaks : noLineBreaks.Substring(0, data.truncate) + " ..";
data.displayName = data.theMessage.Headers.From.DisplayName.ToString();
if (data.displayName == "")
{
data.displayName = data.theMessage.Headers.From.Address.ToString();
}
data.displayName += " <" + data.theMessage.Headers.From.Address.ToString() + ">";
}
}
I believe im supposed to use something called observable collection or something like that? I just cannot see how i can use that here in my program. I hope that some of you guys can assist me in the usage of Observable collection or point me to something else i can use, that does what i need.
I was thinking about using something like timer to achieve it, but im not sure that it would be good practice ?
Create public property for your ListBoxData as follows:
public partial class MainWindow : Window
{
public ObservableCollection<EmailEntry > ListBoxData{get;set;}
public MainWindow()
{
ListBoxData = new ObservableCollection<EmailEntry >();
InitializeComponents();
}
private void newEmail(object sender, DoWorkEventArgs e)
{
List<Message> allEmail = FetchAllMessages(hostname, port, useSsl, username, password);
foreach (Message singleEmail in allEmail)
{
var mailData = new ListBoxDataClass { theMessage = singleEmail, truncate = 40 };
readyUpListBoxData(mailData);
ListBoxData.Add(new EmailEntry { from = mailData.displayName, subject = mailData.partOfBody, messageID = singleEmail.Headers.MessageId.ToString() });
}
}
You can either implement INotifyPropertyChanged and then raise ListBoxData property when you're done adding or just change your ListBoxData to ObservableCollection because it implements INPC by default.

Categories

Resources