Passing class object to second window wpf - c#

I've searched around online quite a bit and have come up short. How can I pass an instance of a class object to a second popup window and return the changes only if the user clicks ok.
For example say you have a list of people and when you double click a person in the list an edit window appears. In the edit window would be a textbox displaying the person's name where users could change it. The change would only be committed back to the main view model if the user hits the 'OK' button. Otherwise the changes would be dismissed. Ideally this edit window would be modal.
How can I do this?

Let's say you have a person object that you want to modify called Joe so: public Person Joe = new Person(); When you create your new window just say NewWindow window = new NewWindow(Joe);. Then in your NewWindow Constructor let it accept a person object like so
Person aPerson;
NewWindow(Person inPerson)
{
aPerson = inPerson
}
Now when the user clicks on the save button modify whatever fields of aPerson that you need to modify. You can use something like an event to send it back to the original view. Would have put this in a comment, but the code blocks make it easier to read.

Related

Passing Details From One Window to Another Window

I have a selection of TextBoxes that a user fills in when they wish to note that they have had contact with another person. Most of the TextBoxes are imply filled in by typing into them. However, for one of them I would like the user to be able to select from a list of People that appears when they click on a button.
This is where I am having problems. So far I have just made a DataGrid appear and handled it's SelectionChanged method to fill in the TextBoxes text property. This has worked fine, however now there is not enough space on the current page to show an entire DataGrid with all the people they can select from.
I've decided to show the People in a separate, smaller Window that appears when the user clicks a Button. The issue I have is that when the user selects the Person they wish to mark the contact for in the new Window, I have no idea how I can notify the original Window that a Person has been selected, close the new smaller Window and fill in the appropriate TextBox on the original Window.
What would be the most intuitive way to fill in the TextBox on the original Window, based on the selection on the Window that opens?
I would use delegates,which call a function of the original window and parse the changed variable with it. So you know when the user clicked something and you can directly react to this "event".
Link:
https://msdn.microsoft.com/en-us/library/ms173171.aspx
If you use a framework like Galasoft's MVVM Light (http://www.galasoft.ch/), they have a messenger system just for this purpose. It allows you to "broadcast" messages that can be "received" by any other part of the application
This is when considering using Domain, Model, Presentation (Winforms/WPF version of MVC formatting) to do your app.
You can have each form as its own class, well they are their own class. Create each form class but add some public members to it if the controls are private. Have them have "get" properties only and to return the values of whatever controls or variables are in that form. Your main form will be the controlling form. All forms will be handled by the main form so when you open it, it is a class the main form can access.
Now, if I remember (been doing more MVC and not any Winforms lately) I believe if you use the ShowDialog() method it will freeze the main thread so when you close out the main form you can continue and read in public members you have in your forms class you opened. Synchronous I believe it runs as. If you use just Show() the thread will keep on trucking, asynchronous. With asynchronous you may then have to use a main form in your startup code so there is always a window there but subscribe to the close event of your forms and have a method that can grab those public members out. Be sure to instantiate the extra forms at the root of the main class so it doesn't fall out of scope when it exists the method that calls it. You may even be able to make the method that calls is a async call and have an await before the command that runs the Show method on the form.
Summary, treat each form as its own class but add public members that can read the values from the controls and/or variables you want. Read that data from the class when it closes via an event or synchronously when the thread closes out from the form closing. The form closing doesn't discard the object, just the visualization of the form.
Oh, if you are passing info from the main form to a child for you are opening, either add a constructor for that form class that takes your input as a model or values to fill in the appropriate variables or forms before showing it or create a public property you can put your values you want to send in before showing the class.
Remember, everything is a class, once you look at it as such and treat it as such, the answer will come. :-)
I should warn, I am a long winded explainer.
At work putting all this down from memory so some errors may exist. Let me know if there are.
I think the problem is to access the controls of the main window, isn`t it?
You can define an event of changing user`s choise and access MainWindow control by using the following construction:
((MainWindow)Application.Current.MainWindow).MyTextBox

C# Passing string from one form to another

I have 2 forms called, Main and Kitchen.
In Main I have a textbox called detailName, I need to pass the value of detailName.Text from Main to Kitchen to a TextBox called orderBox.
Kitchen newKitchenForm = new Kitchen();
newKitchenForm.OrderBox.Text = detailName.Text;
That is my code for it but it does not seem to work.
Any help would be appreciated.
Further information:
I'm programming a order food through touchscreen type of thing, so I want the thing that the client orders to be displayed to both the client and to the kitchen, hence the form name "Kitchen".
So after a button called "lockOrder_In" is pressed, I want the food they just chose to be shown to the person ordering and to the kitchen. Here is my code for that button.
private void lockOrder_Click(object sender, EventArgs e)
{
Dish_1.Text += Environment.NewLine + detailName.Text;
Price_1.Text += Environment.NewLine + detailPrice.Text;
// Show the order in the kitchen form
Kitchen newKitchenForm = new Kitchen();
newKitchenForm.ordersBox.Text = detailName.Text;
}
I got the client side to work, but the person order is able to see what they ordered but on the other form "Kitchen" they are not. The food Name which is shown in "detailName.Text" in form "Main", is not displayed in "Kitchen" Form in "orderBox.Text".
You can send it as a parameter in the Kitchen form constructor or define a public property in Kitchen and set its value to the textbox's text property.
This can be achieved easily by creating an instance of Form 1 in Form 2. This is one of the approach.
Follow the steps:
In Form 1 : Make sure that your control is public.
eg: txtForm1.Text = "Bangalore";
In Form 2 :
Step 1: Create an instance of Form 1 globally. If the instance is created locally the value contained by the control cannot be accessed, only null value will be returned even the data has been populated to it.
Step 2 : Retrieve the control's value by Form 1's instance.
eg: Form1 frm1 = new Form1();
string Form1Value = frm1.txtForm1.Text
for more details MSDN Link

Assigning textbox value to a field in a separate form

I am sure this is an easy question to answer, but I am having difficulty implementing it how I need.
I am using Visual Studio 2013 and C#
I have two forms, one that loads when the app starts up which contains user-selectable settings such as user id, how many puzzle pieces that would like on screen... and a confirm button.
The second form is like a puzzle grid, which is generated when the user clicks the confirm button on the first form.
When the person has correctly solved the puzzle, a message box pops up with the time it took to solve.
What I want to be able to do is add the user id field into the messagebox string.
I have seen many examples of using event args and getting and setting fields but most are assuming one form is generated from a previous form, where I just want to 'grab' the information from one form and store it on the second form for use in a string.
Links to tutorials would also be appreciated if that is easier.
I found out what I was doing wrong, with the help of everyone's answers.
I had the variables declared on the first form, but they were declared in the textbox_leave and updownBox_leave methods when they should have been declared at the very top of the class.
Then I just called Form1.IdString and Form1.puzzleNumberString from my Form2 and what-do-you-know everything went as I thought it should.
It's pretty simple.All you need to do is pass your id variable to second form constructor.For example in your Confirm Button click:
Form2 f2 = new Form2(myVariable);
f2.Show();
And you should add a constructor to the Form2:
public string ID { get; set; }
public Form2(string id)
{
InitializeComponent();
ID = id;
}
Then you can use ID variable in your second form.
In your puzzle form create a global Form variable, then give the constructor a Form f parameter and set your global form variable as the passed parameter:
public Form form = null;
public PuzzleForm(Form f) //puzzle form constructor
{
form = f;
}
then go into your first form and where you create an instance of the puzzle form change it so that it passes an instance of this.
PuzzleForm pf = new PuzzleForm(this);
Now from inside your Puzzle form you can access your Form1 variables like so MessageBox.Show("UserID: "+form.userID.Text);

GUI - related, how do I(after clicking a control), stop one form and resume code execution after the opened form is closed?

I know the question isn't very clear, I will try to explain, can't provide code because most of the variables are written in my language so you wouldn't be able to understand them.
I'm writing a simple software that maintains a list of cars, their owners and repairs made on the cars(I've developed 3 separate classes for cars, owners, and repairs). Important info is that each car has an attribute which is a list of repairs done to it, and my idea was as follows: I made a form which allows you to enter relevant data about the owner and the car and containing a checkbox saying Has repairs, and a button to add a new object to the list. When I click this button, it checks the status of the checkbox, if it is checked, a new form opens whose constructor receives references to a list and a car containing 2 buttons, 1 to exit the form, the other one to add repairs to the said list. But what happens is, I click the button, and it adds the car while the other form is still in the air, not doing what I need it to do, since the car is already in the list.
To be clear, I need a way to make the code execution stop when I enter this new form, and resume when I leave it. Any help would be welcome!
form1.Show() shows a form and continues execution once the form is opened.
Try form1.ShowDialog() - this makes the form modal, meaning it will hold code execution until you close the form.

How can I transfer information to another form without using static forms?

I have a Windows form that's generated using code (including buttons and what not). On it, amongst other things, there is a text box and a button. Clicking the button opens a new Windows form which resembles an Outlook contact list. It's basically a data grid view with a few options for filtering. The idea is that the user selects a row in this home-made contact book and hits a button. After hitting that button, the (second) form should close and the email address the user selects should be displayed in the text box on the first form.
I cannot use static forms for this purpose, so is there any way to let the first form know the user has selected something on the second firm? Can you do this with events, or is there another way? Mind that I hardly know anything about delegates and forms yet.
Please advise.
Edit 1 = SOLVED
I can return the email address from the second form to the first form now, but that brings me to another question. I am generating controls and in that process I'm also generating the MouseClick eventhandler, in which the previous procedure for selecting a contact is put.
But how do I, after returning the email address in the MouseClick eventhandler, insert that information into a generated text box? Code to illustrate:
btn.MouseClick += new MouseEventHandler(btn_MouseClick);
That line is put somewhere in the GenerateControls() method.
void btnContacts_MouseClick(object sender, MouseEventArgs e)
{
using (frmContactList f = new frmContactList())
{
if (f.ShowDialog(fPrompt) == DialogResult.Cancel)
{
var address = f.ContactItem;
MessageBox.Show(address.Email1Address.ToString());
}
}
}
That appears separately in the class. So how do I put the email address into a text box I previously generated?
Forms in .Net are normal classes that inherit from a Form class.
You should add a property to the second (popup) form that gets the selected email address.
You should show the popup by calling ShowDialog.
This is a blocking call that will show the second form as a modal dialog.
The call only finishes after the second form closes, so the next line of code will run after the user closes the popup.
You can then check the property in the second form to find out what the user selected.
For example: (In the first form)
using(ContactSelector popup = new ContactSelector(...)) {
if (popup.ShowDialog(this) == DialogResult.Cancel)
return;
var selectedAddress = popup.SelectedAddress;
//Do something
}
In response to my first edit, this is how I solved it. If anyone knows how to make it more elegant, please let me know.
void btnContacts_MouseClick(object sender, MouseEventArgs e)
{
using (frmContactList f = new frmContactList())
{
if (f.ShowDialog(fPrompt) == DialogResult.Cancel)
{
var contact = f.ContactItem;
TextBox tbx = ((Button)sender).Parent.Controls[0] as TextBox;
tbx.Text = contact.Email1Address;
}
}
}
You should keep a reference to your generated TextBox in a variable (private field in your class) and use this instead of looking it up in the Controls array. This way your code would still work even if you some time in the future change the location it has in the array, and you would get a compiler message if you removed that field, but forgot to remove the code that used it.
If the second form is modal, I would recommend that rather than having the first form create an instance of the second form and use ShowModal on it, you should have a Shared/static function in the second form's class which will create an instance of the second form, ShowModal it, copy the appropriate data somewhere, dispose the form, and finally return the appropriate data. If you use that approach, make the second form's constructor Protected, since the form should only be created using the shared function.

Categories