I am developing window application POS. Requirement is: when user click on button 'seach item' on _mainform(form 1) then it open _Searchform(form2) and on the search form it display result in listview with select item button on form3 and close _searchform(form2). The item that we selected from listview , we add in _mainform(form1) listview.
I try to implement this functionality with delegate and event. On form3 (search result form) i have declared delegate and event and subscribe that even on form1(main form). but when i run application event on form 1 dot get fired.
following this code:
_mainform(form1):
namespace KasseDelegate
{
public delegate void ListViewUpdatedEventHandler(object sender, ListViewUpdatedEventArgs e);
public partial class Form1 : Form
{
private Form3 frm3;
public Form1()
{
InitializeComponent();
frm3 = new Form3();
frm3.ListViewUpdated += new ListViewUpdatedEventHandler(Frm3_ListViewUpdated1);
}
private void Frm3_ListViewUpdated1(object sender, ListViewUpdatedEventArgs e)
{
MessageBox.Show("hi");
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
}
}
}
_searchform(form2) :
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (SQLiteConnection con = new SQLiteConnection(Properties.Settings.Default.ConnectionString))
{
con.Open();
SQLiteCommand cmd = new SQLiteCommand("select * from varer where varenummer=#Varenummer", con);
cmd.Parameters.AddWithValue("#Varenummer", "101");
SQLiteDataReader dr = cmd.ExecuteReader();
Form3 frm3 = new Form3(dr);
frm3.Show();
}
}
}
form 3:
namespace KasseDelegate
{
public partial class Form3 : Form
{
public event ListViewUpdatedEventHandler ListViewUpdated;
SQLiteDataReader dr1;
public Form3()
{
InitializeComponent();
}
public Form3(SQLiteDataReader dr)
{
InitializeComponent();
dr1 = dr;
}
private void Form3_Load(object sender, System.EventArgs e)
{
if (dr1 != null)
{
while (dr1.Read() == true)
{
ListViewItem LVI = new ListViewItem();
LVI.SubItems.Add(dr1[0].ToString());
LVI.SubItems.Add(dr1[1].ToString());
LVI.SubItems.Add(dr1[2].ToString());
LVI.SubItems.Add(dr1[3].ToString());
LVI.SubItems.Add(dr1[4].ToString());
listView1.Items.Add(LVI);
}
}
}
private void button2_Click(object sender, System.EventArgs e)
{
string sVareNummer = listView1.SelectedItems[0].SubItems[1].Text;
string sBeskrivelse = listView1.SelectedItems[0].SubItems[2].Text;
string pris = listView1.SelectedItems[0].SubItems[4].Text;
string enpris = listView1.SelectedItems[0].SubItems[5].Text;
if (ListViewUpdated != null)
{
ListViewUpdated(this, new ListViewUpdatedEventArgs() { VareNummer1 = sVareNummer, Beskrivelse1 = sBeskrivelse, Pris1 = pris, Enpris1 = enpris });
}
}
}
public class ListViewUpdatedEventArgs : System.EventArgs
{
private string VareNummer;
private string Beskrivelse;
private string pris;
private string enpris;
public string VareNummer1
{
get
{
return VareNummer;
}
set
{
VareNummer = value;
}
}
public string Beskrivelse1
{
get
{
return Beskrivelse;
}
set
{
Beskrivelse = value;
}
}
public string Pris1
{
get
{
return pris;
}
set
{
pris = value;
}
}
public string Enpris1
{
get
{
return enpris;
}
set
{
enpris = value;
}
}
}
}
So how i can get values of listview selected item from form3(displayitem) to form1.(mainform).
If I understand it correctly you have Form1 - which launches Form2 which in turn launches Form3. On selecting some item on Form3 you need to update it back on Form1.
So declare a delegate on Form1. Pass this delegate to Form2 [Form2 constructor should accept this as a default parameter - so that if Form2 is triggered from some other place we need not have hard dependency on delegate.]
maintain a private variable of this delegate type on Form2 and while launching Form3 pass the same delegate to Form3 constructor.
On Form3 you have the delegate now which is holding a reference to a method on From1, so whenever an item is selected you can assign this delegate on Form3 which will fire the method on Form1.
so here is an working example.
public delegate void MyDelegate(string selectedItem);
public class Form1
{
private MyDelegate delegate1;
public Form1()
{
delegate1 = new MyDelegate(ShowSelectedItem);
var form2 = new Form2(delegate1);
}
public void LaunchForm2()
{
}
private void ShowSelectedItem(string result)
{
}
}
public class Form2
{
private MyDelegate form2Delegate;
public Form2(MyDelegate del = null)
{
form2Delegate = del;
var form3 = new Form3(form2Delegate);
}
public void LaunchForm3()
{
}
}
public class Form3
{
private MyDelegate form3Delegate;
public Form3(MyDelegate del = null)
{
form3Delegate = del;
SelectedItemTriggered("tes");
}
public void SelectedItemTriggered(string selectedItem)
{
form3Delegate(selectedItem);
//This will trigger method ShowSelectedItem of Form1
}
}
You could set up an event in your Form3 and access it from outside like this:
public partial class Form2 : Form
{
public Form2()
{
Form3 new3 = new Form3();
// Access the event of form3 from outsite
new3.DisplayedItemChanged += ItemChanged;
}
public void ItemChanged(object sender, EventArgs e)
{
// This will be triggered.
}
}
public class Form3 : Form
{
// Create an event
public event EventHandler DisplayedItemChanged;
public void button1_Click(object sender, EventArgs e)
{
if (this.DisplayedItemChanged != null)
{
// Raise the event and pass any object
this.DisplayedItemChanged(yourObjectToPass, e);
}
}
}
According your comments below:
public partial class Form1 : Form
{
public Form1()
{
// This one is an instance of Form3
Form3 newForm = new Form3();
newForm.SomethingHappens += RaiseHere;
}
public void RaiseHere(object sender, EventArgs e)
{
// Do something...
}
}
public partial class Form2 : Form
{
public Form2()
{
// This one is NOT the same as on Form1. Its a NEW form.
Form3 newForm = new Form3();
newForm.Show();
}
}
public partial class Form3 : Form
{
public event EventHandler SomethingHappens;
public Form3()
{
//...
}
}
This wont work, never. You have to use the same instance:
Form3 newForm = new Form3();
newForm.SomethingHappens += RaiseHere;
newForm.Show();
If this isnt clear for you I cant help, sorry:
Related
English is not my native language so please bear with me.
What I meant by my question is that how would one make a form (form 2, for example) display what is being typed from form 1, like in real time. I assume the
TextChanged event would be used but what's the next step?
To keep it simple and OOP-friendly, I would make a property in Form2 and update it in the Form1.TextChanged event:
Form1.cs
public partial class Form1 : Form
{
private Form2 _form2;
public Form1()
{
InitializeComponent();
this.textBox1.TextChanged += (sender, e) =>
{
_form2.TextBoxValue = textBox1.Text;
};
_form2 = new Form2();
_form2.Show();
}
}
Form2.cs
public partial class Form2 : Form
{
public string TextBoxValue
{
get => textBox1.Text;
set => textBox1.Text = value;
}
public Form2()
{
InitializeComponent();
}
}
Note that you would need to change the Form1 and Form2 names to the actual form class names in your application (as well as the textBox1 name).
Edit:
As requested in the comments, if you want changes to either textbox to be updated in both forms, you need to add the TextBoxValue property to both forms, and make the event handlers in both forms change that property. I've also cleaned up the code a little.
Form1.cs
public partial class Form1 : Form
{
private Form2 _form2;
public string TextBoxValue
{
get => textBox1.Text;
set => textBox1.Text = value;
}
public Form1()
{
InitializeComponent();
this.textBox1.TextChanged += (sender, e) =>
{
_form2.TextBoxValue = textBox1.Text;
};
_form2 = new Form2();
_form2.Show();
}
}
Form2.cs
public partial class Form2 : Form
{
private Form1 _form1;
public string TextBoxValue
{
get => textBox1.Text;
set => textBox1.Text = value;
}
public Form2()
{
InitializeComponent();
this.textBox1.TextChanged += (sender, e) =>
{
_form1.TextBoxValue = textBox1.Text;
};
this.Shown += (sender, e) =>
{
_form1 = (Form1)Application.OpenForms["Form1"];
};
}
}
Throw an event on form2 and call it from form1
On Form1:
private Form2 frm2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var text = Textbox1.Text;
frm2.TextChanged.Invoke(text , new EventArgs());
}
private void Form1_Load(object sender, EventArgs e)
{
frm2 = new Form2();
frm2.Show();
}
and on form2:
public EventHandler TextChanged;
public Form2()
{
InitializeComponent();
TextChanged += HandleTextChanged;
}
private void HandleTextChanged(object sender, EventArgs e)
{
label1.Text = (string) sender;
}
I prefer not to let the two forms know each other.
You can instead do something like this:
static class Program
{
private static Form _form1;
private static Form _form2;
public static void Main()
{
_form1 = new MyForm();
_form2 = new MyForm();
_form1.MyTextbox.OnTextChanged += Form1_MyTextBox_TextChanged;
}
private void Form1_MyTextBox_TextChanged(object sender, EventArgs e)
{
_form2.MyTextBox.Text = _form1.MyTextbox.Text;
}
}
}
public class MyForm : Form
{
public TextBox MyTextBox {get;set;}
}
I have two Forms:
Form1
Form2
Whenever I check/uncheck a CheckBox checkBox1 on Form2 I want to update textbox1.Readonly that is on Form1. If both textbox1 and checkbox1 had been on the same Form it would be easy go:
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
textbox1.Readonly = checkBox1.Checked;
}
What shall I do in my case when textbox1 and checkbox1 are on different Forms?
You can put it like this:
public partial class Form1: Form {
...
// textBox1 is private (we can't access in from Form2)
// so we'd rather create a public property
// in order to have an access to textBox1.Readonly
public Boolean IsLocked {
get {
return textBox1.Readonly;
}
set {
textBox1.Readonly = value;
}
}
}
...
public partial class Form2: Form {
...
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
// When checkBox1 checked state changed,
// let's find out all Form1 instances and update their IsLocked state
foreach (Form fm in Application.OpenForms) {
Form1 f = fm as Form1;
if (!Object.RefrenceEquals(f, null))
f.IsLocked = checkBox1.Checked;
}
}
}
You should use events and delegates.
On Form2, We're create a delegate and event
public delegate void OnCheckedEventHandler(bool checkState);
public event OnCheckedEventHandler onCheckboxChecked;
public void checkBox1_Checked(object sender, EventArgs e)
{
if (onCheckboxChecked != null)
onCheckboxChecked(checkBox1.Checked);
}
And on Form1, we're realize this event:
void showForm2()
{
Form2 f2 = new Form2();
f2.onCheckboxChecked += onCheckboxChecked;
f2.Show();
}
public void onCheckboxChecked(bool checkState)
{
textBox1.ReadOnly = checkState;
}
For simplier and more flexible
Form1:
public class Form1 : System.Windows.Forms.Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 tmpFrm = new Form2();
tmpFrm.txtboxToSetReadOnly = this.txtMyTextBox; //send the reference of the textbox you want to update
tmpFrm.ShowDialog(); // tmpFrm.Show();
}
}
FOrm2:
public class Form2 : System.Windows.Forms.Form
{
public Form2()
{
InitializeComponent();
}
TextBox _txtboxToSetReadOnly = null;
public TextBox txtboxToSetReadOnly
{
set{ this._txtboxToSetReadOnly = value; }
get {return this._txtboxToSetReadOnly;}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if( this._txtboxToSetReadOnly != null) this._txtboxToSetReadOnly.ReadOnly = checkbox1.Checked;
/*
or the otherway
if( this._txtboxToSetReadOnly != null) this._txtboxToSetReadOnly.ReadOnly = !checkbox1.Checked;
*/
}
}
Please, i need help to send data from a textbox to a listview (column quantity) of another form.
I have in form1
namespace officine
{
public partial class FormClav : Form
{
public FormClav()
{
InitializeComponent();
}
......
private void validation_Click(object sender, EventArgs e)
{
// need code here
// onclik thisend textbox1 to listview1 in formOrd
}
I have a lisview1 in a second form
I fill this listview from a dabase after getting bar code.
Then I call form1 (a numeric keyboard) to change quality column..
So I need to send data from Textbox1 (in FormClav ) to lisview1 in FormOrdo
namespace officine
{
public partial class FormOrdo : Form
{
.......
private void loadproduct()
{
listView1.Items.Clear();
cn.Open();
cmd.CommandText = "select * from vente";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
string[] row = { dr[1].ToString(), dr[2].ToString()};
var listViewItem = new ListViewItem(row);
listView1.Items.Add(listViewItem);
}
}
cn.Close();
}
any idea pls?
You can set a public variable in FormClav and put there the value that you need.
public partial class FormClav : Form
{
public FormClav()
{
InitializeComponent();
}
public string yourvalue = ""
}
private void validation_Click(object sender, EventArgs e)
{
yourvalue = textbox1.text;
}
Try passing a delegate when you instantiate the second form that points to a thread-safe method in the first form that can update your listview.
Hello to past textbox value to another form use this code:
private void validation_Click(object sender, EventArgs e)
{
form2 a = new form2();
a.MdiParent = this.MdiParent; // sets form2 as 'parent window'
a.value = yourTextBox.Text; // sets variable 'value' in form2 equal to yourTextBox value after button is clicked
a.Show(); //opens form2
}
In form 2 generate get set value
public string value { get; set; }
Now you can operate with value easily.
e.g. listView1.Items.Add(value);
On form load adding to listView:
private void Form2_Load(object sender, EventArgs e)
{
listView1.Items.Add(value);
}
Edit:
public partial class Form1 : Form
{
Form2 Frm2;
public Form1()
{
InitializeComponent();
Frm2 = new Form2(this);
}
private void button1_Click(object sender, EventArgs e)
{
Frm2.Show();
Frm2.textBox1.Text = "From Form1";
}
}
public partial class Form2 : Form
{
Form1 Frm1;
public Form2(Form1 F)
{
InitializeComponent();
Frm1 = F;
}
private void button1_Click(object sender, EventArgs e)
{
Frm1.textBox1.Text = "From Form2";
Frm1.listView1.Items.Add(textBox1.Text);
}
}
Basically when a user enters data into a textfield on Form2, I want that data to be stored into a variable then when users selects the button enter, Form2 will hide and Form1 will appear. I then want Form1 to display the data entered in the textfield from Form2 in a new textfield.
This is my attempt, but it doesn't work
On Form 2...
public string Player1 {get; set;}
private void pvpPlay_Click(object sender, EventArgs e)
{
Player1 = txtPlayer1.Text;
Form1 op = new Form1();
op.Show();
this.Hide();
}
Then on Form1 to call this I put...
Form2 f = new Form2();
txtTest.Text = f.Player1;
But it doesn't work. Hopefully someone knows the answer.
I would prefer the using of a simple Callback function like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public String SomeProperty { get; set; }
private void OpenFormButton_Click(object sender, EventArgs e)
{
var secondForm = new Form2()
{
GetSomeProperty = () => { return SomeProperty ;};
};
this.Hide(); //The best way to hide!
secondForm.Show();
}
private void Form1_Load(object sender, EventArgs e)
{
SomeProperty = "HELLO WORLD";
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Func<string> GetSomeProperty
{
get;
set;
}
private void Form2_Load(object sender, EventArgs e)
{
MessageBox.Show(GetSomeProperty.Invoke());
}
}
Everytime you call GetSomeProperty.Invoke(); the Func will call the get accessor and return it from the first Form
What you can do is overload the Form1 constructor.
public Form1(string s)
{
txtTest.Text=s;
}
When calling from Form2
Form1 op = new Form1(Player1);
I have two forms named form1 and form2:
form1 is made of a label and a button.
form2 is made of a textBox and a button
When I click the form1 button, this will show up form2. Any inputs in textBox should be written back to form1.label once I hit the button in form2.
I have the code below but it doesn't work.
// Code from Form 1
public partial class Form1 : Form
{
public void PassValue(string strValue)
{
label1.Text = strValue;
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 objForm2 = new Form2();
objForm2.Show();
}
}
// Code From Form 2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1 objForm1 = new Form1();
objForm1.PassValue(textBox1.Text);
this.Close();
}
}
And a screenshot:
How can I realize that?
You don't access your form1, from which you created form2. In form2 button1_Click you create new instance of Form1, which is not the same as initial. You may pass your form1 instance to form2 constructor like that:
// Code from Form 1
public partial class Form1 : Form
{
public void PassValue(string strValue)
{
label1.Text = strValue;
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 objForm2 = new Form2(this);
objForm2.Show();
}
}
// Code From Form 2
public partial class Form2 : Form
{
Form1 ownerForm = null;
public Form2(Form1 ownerForm)
{
InitializeComponent();
this.ownerForm = ownerForm;
}
private void button1_Click(object sender, EventArgs e)
{
this.ownerForm.PassValue(textBox1.Text);
this.Close();
}
}
Like mentioned in other posts, you won't be able to reference the original Form1 by creating a new instance of Form1. You can pass Form1 into Form2's constructor or expose Form2's text as a public property, but I usually prefer using delegates for this to maintain loose coupling.
// Code from Form 1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 objForm2 = new Form2();
objForm2.PassValue += new PassValueHandler(objForm2_PassValue);
objForm2.Show();
}
public void objForm2_PassValue(string strValue)
{
label1.Text = strValue;
}
}
// Code From Form 2
public delegate void PassValueHandler(string strValue);
public partial class Form2 : Form
{
public event PassValueHandler PassValue;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (PassValue != null)
{
PassValue(textBox1.Text);
}
this.Close();
}
}
When you are doing:
Form1 objForm1 = new Form1();
objForm1.PassValue(textBox1.Text);
... you are creating a new Form1 and calling the PassValue method on the wrong Form1 object. Instead, you could do:
public partial class Form1 : Form
{
// This is the text that will be entered in form2
public String form2text;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Show form2
Form2 objForm2 = new Form2(this);
objForm2.ShowDialog();
// When form2 is closed, update the label text on form1
label1.Text = form2text;
}
}
public partial class Form2 : Form
{
// This is the instance of Form1 that called form2
private Form1 form1caller;
public Form2(Form1 form1caller)
{
InitializeComponent();
this.form1caller = form1caller;
}
private void button1_Click(object sender, EventArgs e)
{
// Pass the textBox value to form1 before closing form2
form1caller.form2text = textBox1.Text;
this.Close();
}
}
I just tried this code and it works, sure it will help you.
in the first form (Form1) type below:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f = new Form2(textBox1.Text);
f.ShowDialog();
}
}
in the second form (Form2) use below codes:
public partial class Form2 : Form
{
public Form2( string st)
{
InitializeComponent();
textBox1.Text = st;
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
You could do this:
class Form2
{
public string ReturnedText = "";
private void button1_Click(object sender, EventArgs e)
{
ReturnedText = textbox1.Text;
Close();
}
}
and in form1
Form2 objForm2 = new Form2();
objForm2.ShowDialog();
string ret = objForm2.ReturnedText;
You should pass reference on form1 to form2 instead of creating new instance in this code:
private void button1_Click(object sender, EventArgs e)
{
Form1 objForm1 = new Form1(); // ← this is another form1, not that you see
objForm1.PassValue(textBox1.Text);
this.Close();
}
The way that I normally approach this requirement is as follows:
I place a public property on the Form2 class:
public string ValueFromForm1 { get; set; }
//In the constructor, or other relevant method, I use the value
public Form2()
{
form2LabelToDisplayForm1Value.Text = ValueFromForm1;
}
In order to return something to Form1, you need to add a public property to the Form1 class to receive the value, and then send a reference to the form to Form2, so that Form2 can set the value:
//Add reference property to Form2 class
public Form1 CallingForm { get; set; }
//Form2 can access the value on Form1 as follows:
private someMethod()
{
this.CallingForm.ValueFromForm2 = "Info coming from form 2";
}
then
//Add public property to Form1 class
public string ValueFromForm2 { get; set; }
//When Form2 is created, set the reference property
Form2 objForm2 = new Form2();
objForm2.CallingForm = this;
objForm2.Show();
Since Form2 now has a reference to the Form1 that created, there is no need to call new Form1() anywhere in Form2. All Form2 has to do is set the value on the reference, and then close itself.
This is what you are going to do:
// Code from Form 1
public partial class Form1 : Form
{
public string MyValue { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 objForm2 = new Form2();
objForm2.textBox1.Text = MyValue;
objForm2.MainForm = this;
objForm2.Show();
}
}
// Code From Form 2
public partial class Form2 : Form
{
public Form1 MainForm { get; set; }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainForm.MyValue = textBox1.Text;
MainForm.Show();
this.Close();
}
}
Form 1 code...:-
namespace Passing_values_from_one_form_to_other
{
public partial class Form1 : Form
{
string str;
private String value1;//taking values from form no _of_test_cases
public string value
{
get { return value1; }
set { value1 = value; }
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.Text = str;
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
str = f2.passvalue;
}
}
}
Form 2 code....:-
namespace Passing_values_from_one_form_to_other
{
public partial class Form2 : Form
{
private string str;
public string passvalue
{
get { return str; }
set { str = value; }
}
public Form2()
{
InitializeComponent();
}
private void Btn_Ok1_Click(object sender, EventArgs e)
{
passvalue = textBox1.Text;
this.Close();
}
}
}
directly execute it u will get the clear picture....same way u can pass values from one form to other...
post your comments if you face any issues...
hope this will help...
or else you can refer this video...
http://www.youtube.com/watch?v=PI3ad-TebP0