How to Return a Value from a Form in C#

How to return a value from a Form in C#?

Create some public Properties on your sub-form like so

public string ReturnValue1 {get;set;} 
public string ReturnValue2 {get;set;}

then set this inside your sub-form ok button click handler

private void btnOk_Click(object sender,EventArgs e)
{
this.ReturnValue1 = "Something";
this.ReturnValue2 = DateTime.Now.ToString(); //example
this.DialogResult = DialogResult.OK;
this.Close();
}

Then in your frmHireQuote form, when you open the sub-form

using (var form = new frmImportContact())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
string val = form.ReturnValue1; //values preserved after close
string dateString = form.ReturnValue2;
//Do something here with these values

//for example
this.txtSomething.Text = val;
}
}

Additionaly if you wish to cancel out of the sub-form you can just add a button to the form and set its DialogResult to Cancel and you can also set the CancelButton property of the form to said button - this will enable the escape key to cancel out of the form.

Windows Form Application how return value form one form to other

You can use different ways to do this.

The simplest is to use Dialogs. You can open your Form2 as fialog by call ShowDialog and then just read the property if result is OK. It's a general way to implement your behavior in WinForms.

private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
// Show testDialog as a modal dialog and determine if DialogResult = OK.
if (form2.ShowDialog(this) == DialogResult.OK)
{
// Read the contents of testDialog's TextBox.
this.txtResult.Text = form2.TextBox1.Text;
}
}

Note that you must set DialogResult property in Form2 to DialogResult.OK if user click the button and DialogResult.Cancel in other way. It helps you to handle scenario when user has decided not to add new movie.

The other way is to use events. Declare new event in Form2 and subscribe Form1 to this event. Raise new event on button click and pass your data as a parameter of your event.

c# Form return value?

You could a string property to the form that will contain the value. It will simply expose the value of the private email field.

For example:

public class SomeForm : Form
{
public string Email
{
get
{
return txtEmail.Text;
}
}
}

and then from some outside form you could show the form and read the value that was entered into the Email field once the form is closed:

using (var form = new SomeForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string email = form.Email;
// do something with the email
}
}

How to return a value from Windows Form

If I understand you right you have some kind of Text Field in Form1 in which a user enters his/her name. And you need to return that value back to the function that calls Application::Run(Form^)

To accomplish this I would not create an instance of Form1 anonymously. I would make a pointer / reference to it so that I have access to it after its construction.

Form1^ form1 = gcnew Form1();
Application::Run(form1);

Then you need to do some stuff in your Form1 class. First you need to save the Text of your Input Field when you click on that Button, because the Form will invalidate all components on Dispose. Add a click handler on the button click event to save the Text of your input component (in this example a TextBox) in a Class Member Variable:

class Form1 [...]
{
[...]
private:
System::String^ m_Name; // Create a member variable for the value
[...]
}

// Add a click Handler for your Button (do this in the Designer) and save the Text of the Text Box in it
System::Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e)
{
m_Name = textBoxName->Text;
}

Then I would add a getter Method for the saved value that you can later call by your main Method:

System::String^ Form1::getUsername()
{
return this->m_Name; // return the last saved Text of your Input control
}

Application::Run() stops the executing thread as long as the Form displays, so in your Project08.cpp file you would have:

[...]
Form1^ form1 = gcnew Form1(); // Create the instance and keep a pointer to it
Application::Run(form1); // Display the Form
System::String^ name = form1->getUsername(); // Get the saved Name after the Form disposed
// Do stuff with the name in Form 2
Application:Run(gcnew Form2(name));
[...]

how can I return value from show dialog form?

One option is to pass data from child form to parent form using an event which is invoked when clicking a button on the child form, data is in a validate state invoke the event then set DialogResult to OK.

The following is a conceptual example where the main form opens a child form for adding a new item of type Note.

If all you need is a single property/value this will still work by changing the delegate signature OnAddNote.

Note class

public class Note : INotifyPropertyChanged
{
private string _title;
private string _content;
private int _id;

public int Id
{
get => _id;
set
{
_id = value;
OnPropertyChanged();
}
}

public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged();
}
}

public string Content
{
get => _content;
set
{
_content = value;
OnPropertyChanged();
}
}

public override string ToString() => Title;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

Operations class

NewNote method is called from the child form Add button when data is validated

public class Operations
{
public delegate void OnAddNote(Note note);
public static event OnAddNote AddNote;

public static List<Note> NotesList = new List<Note>();

/// <summary>
/// Pass new Note to listeners
/// </summary>
/// <param name="note"></param>
public static void NewNote(Note note)
{
AddNote?.Invoke(note);
}

/// <summary>
/// Edit note, do some validation
/// </summary>
/// <param name="note"></param>
/// <returns></returns>
public static Note EditNote(Note note)
{
throw new NotImplementedException();
}

/// <summary>
/// Load mocked data, for a real application if persisting data use <see cref="LoadNotes"/>
/// </summary>
public static void Mocked()
{
NotesList.Add(new Note()
{
Title = "First",
Content = "My note"
});
}

/// <summary>
/// For a real application which persist your notes we would load from
/// - a database
/// - file (xml, json etc)
/// </summary>
/// <returns></returns>
public static List<Note> LoadNotes()
{
throw new NotImplementedException();
}

/// <summary>
/// Delete a note in <see cref="NotesList"/>
/// </summary>
/// <param name="note"></param>
public static void Delete(Note note)
{
throw new NotImplementedException();
}

public static Note FindByTitle(string title)
{
throw new NotImplementedException();
}

/// <summary>
/// Save data to the data source loaded from <see cref="LoadNotes"/>
/// </summary>
/// <returns>
/// Named value tuple
/// success - operation was successful
/// exception - if failed what was the cause
/// </returns>
public static (bool success, Exception exception) Save()
{
throw new NotImplementedException();
}
}

Child form

public partial class AddNoteForm : Form
{
public AddNoteForm()
{
InitializeComponent();
}

private void AddButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(TitleTextBox.Text) && !string.IsNullOrWhiteSpace(NoteTextBox.Text))
{
Operations.NewNote(new Note() {Title = TitleTextBox.Text, Content = NoteTextBox.Text});
DialogResult = DialogResult.OK;
}
else
{
DialogResult = DialogResult.Cancel;
}
}
}

Main form

public partial class Form1 : Form
{
private readonly BindingSource _bindingSource = new BindingSource();

public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
Operations.AddNote += OperationsOnAddNote;

Operations.Mocked();

_bindingSource.DataSource = Operations.NotesList;
NotesListBox.DataSource = _bindingSource;
ContentsTextBox.DataBindings.Add("Text", _bindingSource, "Content");
}
private void OperationsOnAddNote(Note note)
{
_bindingSource.Add(note);
NotesListBox.SelectedIndex = NotesListBox.Items.Count - 1;
}
private void AddButton_Click(object sender, EventArgs e)
{
var addForm = new AddNoteForm();
try
{
addForm.ShowDialog();
}
finally
{
addForm.Dispose();
}
}
}

Sample Image

Full source

Dialog Result Set the Return Value

You should set the DialogResult property of the form to exit. Any value but DialogResult.None will force the form to close and return whatever you set as DialogResult (on the form, not on the button)

private void buttonSaveSet_Click( object sender , EventArgs e )
{
setChars = new setChars();
this.DialogResult = DialogResult.Yes;
....
// No need to call Close here
// Close();
}

The behavior you observe is due to the fact that probably the form engine examines the DialogResult property of the button before entering the click event and it is not expected to reevaluate it again at the exit from the event. Thus, your first click sets the property on the button, at the second click the property on the button is noted by the form engine and everything closes.

How to return value from form created with Activator.CreateInstance

It's better to work with typed objects. But here I suppose you want to create object using type name and you don't want / can't to cast the object to desired type.

Even in this case, since you know your forms have an _id field, you can force them to create Id property and in fact force them to implement an interface and when reading value, cast it to he interface.

For example

public interface IFormWithId
{
int Id {get;set;}
}

And implement interface for your classes:

public partial class SomeForm: IFormWithId
{
public int Id {get;set;}
public SomeForm(int id)
{
InitializeComponent();
Id = id;
}
}

Then when reading value use such code:

var id = ((IFormWithId)form).Id;

If for any reason you don't want to use interfaces, you can consider these options:

If _id is private or protected field

If _id is private or protected field and the form doesn't have a property which exposes the field, then the only solution to find its value is using reflecten. For example:

var field = form.GetType().GetField("_id", /*Use GetProperty for property*/
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
var value = field.GetValue(form);

If _Id is a public field or property

You can use dynamic this way:

var id = ((dynamic)form)._id;

Return result between Windows Forms in C#

class Generator : Form
{
public string Text1 { get; private set; }

void ok_Click (object sender, EventArgs)
{
this.Text1 = txt1.Text;
...
this.Close();
}
}

Form gen = new Generator();
gen.ShowDialog();
string text1 = gen.Text1;
...

class TextInfo
{
public string Text1 { get; set; }
...
}

class Generator : Form
{
public TextInfo Textinfo { get; private set; }

public Generator(TextInfo info)
{
this.TextInfo = info;
}

void ok_Click (object sender, EventArgs)
{
this.TextInfo.Text1 = txt1.Text;
...
this.Close();
}
}

TextInfo info = new TextInfo();
Form gen = new Generator(info);
gen.ShowDialog();
string text1 = info.Text1;

Return a value on closing from a form without showdialog

You can handle the OnClosing event of the child form and set a value of a variable of the parent form class before closing.

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Form1.myVar = 3;
}


Related Topics



Leave a reply



Submit