I have two windows forms in my application. First one is Main form and the second one is lookup form. I'm trying to open lookup form from the main form in a text box key leave event and then I'm opening the lookup form. My lookup form has a data grid view and I' loading it in the form load event of the lookup form. I'm reading my selected value on the grid view of the lookup window to an object. I want to close the lookup window as soon as I read the values of the selected row to the object and I want to pass it to the main form? How can I do that?
This is what I have done.
In the main form.
LookupModelType="";
if (e.KeyCode.Equals(Keys.F3))
{
foreach (Form frm in Application.OpenForms)
{
if (frm is FormControllers.Lookup)
{
if (frm.WindowState == FormWindowState.Minimized)
{
frm.WindowState = FormWindowState.Normal;
frm.Focus();
return;
}
}
}
LookupModelType = "Product";
FormControllers.Lookup newLookUp = new FormControllers.Lookup(LookupModelType);
newLookUp.ShowDialog(this);
}
In the lookup window
private string GridType = "";
public Lookup(String LookupModelType)
{
InitializeComponent();
this.GridType = LookupModelType;
}
private void Lookup_Load(object sender, EventArgs e)
{
if (GridType == "Product")
{
using(DataControllers.RIT_Allocation_Entities RAEntity = new DataControllers.RIT_Allocation_Entities())
{
dgvLookup.DataSource = RAEntity.TBLM_PRODUCT.ToList<DataControllers.TBLM_PRODUCT>();
}
}
dgvLookup.ReadOnly = true;
}
private void dgvLookup_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
{
return;
}
int index = e.RowIndex;
dgvLookup.Rows[index].Selected = true;
}
you can do it like blow :
in the Main form :
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F3)
{
LookupForm look = new LookupForm();
var result = look.ShowDialog();
if(result == DialogResult.OK)
{
MessageBox.Show(look.data.ToString());
}
}
}
and in the look up form you have to declare 1 variable and fill whenever cell clicked
public partial class LookupForm : Form
{
public object data = new object();
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
data = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
of course, for better performance, you can declare the variable in specific type
To share data between Parent Child forms using events, here are the things needed:
A public custom event args class to share data.
Child form to have a event.
In your parent form whenever you create an instance of child, you
need to register eventhandlers
Please note that the code below is just a demo code and you will need to add null checks etc. to make it "robust".
Custom event args below
public class ValueSelectedEventArgs : EventArgs
{
public object Value { get; set; }
}
Your lookup form should have the following event declared:
public event EventHandler ValueSelected;
protected virtual void OnValueSelected(ValueSelectedEventArgs e)
{
EventHandler handler = ValueSelected;
if (handler != null)
{
handler(this, e);
}
// if you are using recent version of c# you can simplyfy the code to ValueSelected?.Invoke(this, e);
}
In my case I am firing the event on listbox selected index change and closing the form as well. Code for it:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var i = this.checkedListBox1.SelectedIndex;
ValueSelectedEventArgs args = new ValueSelectedEventArgs();
args.Value = i;
OnValueSelected(args);
this.Close();
}
Finally in the parent form you have to register for the eventhandler
private void textBox1_Leave(object sender, EventArgs e)
{
lookup myLookup = new lookup();
myLookup.ValueSelected += MyLookup_ValueSelected;
myLookup.Show();
}
private void MyLookup_ValueSelected(object sender, EventArgs e)
{
textBox2.Text = (e as ValueSelectedEventArgs).Value.ToString();
}
I personal like to add dynamically the lookup window, and I do something like this:
//examble object
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// the value which you want to get from datagridview
private Person _selectedValue;
// the datagridview datasource, which you neet to set
private IEnumerable<Person> _gridDataSource =
new List<Person>()
{
new Person {FirstName="Bob",LastName="Smith" },
new Person {FirstName="Joe",LastName="Doe"}
};
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.F3)
{
var btnOk = new Button() { Text = "Ok", Anchor= AnchorStyles.None };
var btnCancel = new Button() { Text = "Cancel",Anchor= AnchorStyles.Right };
var dg = new DataGridView();
var bs = new BindingSource();
bs.DataSource = _gridDataSource;
dg.DataSource = bs;
dg.Dock = DockStyle.Fill;
dg.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//setup a layout wich will nicely fit to the window
var layout = new TableLayoutPanel();
layout.Controls.Add(dg, 0, 0);
layout.SetColumnSpan(dg, 2);
layout.Controls.Add(btnCancel, 0, 1);
layout.Controls.Add(btnOk, 1, 1);
layout.RowStyles.Add(new RowStyle(SizeType.Percent));
layout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.Dock = DockStyle.Fill;
//create a new window and add the cotnrols
var window = new Form();
window.StartPosition = FormStartPosition.CenterScreen;
window.Controls.Add(layout);
// set the ok and cancel buttons of the window
window.AcceptButton = btnOk;
window.CancelButton = btnCancel;
btnOk.Click += (s, ev) => { window.DialogResult = DialogResult.OK; };
btnCancel.Click += (s, ev) => { window.DialogResult = DialogResult.Cancel; };
//here we show the window as a dialog
if (window.ShowDialog() == DialogResult.OK)
{
_selectedValue =(Person) bs.Current;
MessageBox.Show(_selectedValue.FirstName);
}
}
}
Related
I'm stuck with the following thing.
I want to change the panel color from another Form(ColorForm).
Is it possible?
Code From the MainForm:
public void upperpanel_Paint(object sender, PaintEventArgs e)
{
}
I don't know how to access that upperpanel_Paint in my ColorForm.
I'm opening ColorForm From SettingsForm
Mainform > SettingsForm > ColorForm
public partial class SettingsForm : Form
{
public static event ColourSettingChangedDelegate ColourSettingsChangedEvent;
public delegate void ColourSettingChangedDelegate(Color color);
List<string> adreses;
List<string> bookmarki;
void SelectColour()
{
using (ColorForm colourForm = new ColorForm())
{
if (colourForm.ShowDialog() == DialogResult.OK)
{
//Update colour setting and fire event
OnColourSettingsChanged(colourForm.SelectedColor);
}
}
}
public SettingsForm(List<string> adr, List<string> s)
{
InitializeComponent();
adreses = adr;
bookmarki = s;
}
private void Historyb_Click(object sender, EventArgs e)
{
foreach (Form form in Application.OpenForms)
{
if (form.GetType() == typeof(HistoryForm))
{
form.Activate();
return;
}
}
HistoryForm hf1 = new HistoryForm(adreses);
hf1.Show();
}
private void Bookmarksb_Click(object sender, EventArgs e)
{
BookmarksForm booklist = new BookmarksForm();
booklist.SetAllBookmarks(bookmarki);
booklist.ShowDialog();
}
private void Colorb_Click(object sender, EventArgs e)
{
SelectColour();
}
private void OnColourSettingsChanged(Color color)
{
if (ColourSettingsChangedEvent != null)
ColourSettingsChangedEvent(color);
}
}
Code from ColorForm:
public partial class ColorForm : Form
{
public ColorForm()
{
InitializeComponent();
}
private void Panelcolor_Click(object sender, EventArgs e)
{
ColorDialog colorDlg = new ColorDialog();
colorDlg.AllowFullOpen = true;
colorDlg.AnyColor = true;
if (colorDlg.ShowDialog() == DialogResult.OK)
{
upperpanel.BackColor = colorDlg.Color;
}
}
}
Thank you!
Perhaps it would be better to fire a global event when the settings change, or the particular form colour setting changes, and listen for that event on the form where you need to take action.
for example see this pseudo code:
ColourForm:
Form used just to pick a colour, and store the result in a property.
class ColourForm
{
public Color SelectedColor {get;set;}
private void Panelcolor_Click(object sender, EventArgs e)
{
ColorDialog colorDlg = new ColorDialog();
colorDlg.AllowFullOpen = true;
colorDlg.AnyColor = true;
if (colorDlg.ShowDialog() == DialogResult.OK)
{
this.SelectedColor = colorDlg.Color;
}
}
void Cancel()
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
void Save()
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
SettingsForm:
The main form for updating settings, this creates a colour picker form and saved the settings and fires an event if the dialog result of the colour form is an 'ok' result.
class SettingsForm
{
public static event ColourSettingChangedDelegate ColourSettingsChangedEvent;
public delegate void ColourSettingChangedDelegate(Color color);
void SelectColour()
{
using (ColourForm colourForm = new ColourForm())
{
if (colourForm.ShowDialog() == DialogResult.OK)
{
//Update colour setting and fire event
OnColourSettingsChanged(colourForm.SelectedColour);
}
}
}
private void OnColourSettingsChanged(Color color)
{
if (ColourSettingsChangedEvent!=null)
ColourSettingsChangedEvent(color);
}
}
On you Main Form:
The Main form listens for a settings / colour changed event and changes the panel colour to the colour specified in the event when it fires.
class MainForm()
{
//Constructor
MainForm()
{
SettingsForm.ColourSettingsChangedEvent += ColourSettingsChanged;
}
void ColourSettingsChanged(Color color)
{
upperpanel.BackColor = color;
}
}
it would be better to have some kind of settings manager class than have the event on the settings form itself but you should get the idea
I am new to C#. I am using windows forms.
As shown in screenshot, I have form1 with 4 buttons and 4 user controls.
click show UserControl1 and UserControl1 shows up.
click show UserControl2 and UserControl2 shows up.
click show UserControl3 and UserControl3 shows up.
click show UserControl4 and UserControl4 shows up.
what I want to do is: when I click Show Previous UC (on User Control4) , the previous User Control shows up.
for example:
click show UserControl2 and UserControl2 shows up.
click show UserControl4 and UserControl4 shows up.
and now I want when I click Show Previous UC, UserControl2 shows up (the previous user control).
How Can I show the previous User Control ( the last one which was shown before the current one)?
Please help me, Thank you.
public partial class Form1 : Form
{
UserControl1 UC1 = new UserControl1();
UserControl2 UC2 = new UserControl2();
UserControl3 UC3 = new UserControl3();
UserControl4 UC4 = new UserControl4();
public Form1()
{
InitializeComponent();
Controls.Add(UC1);
Controls.Add(UC2);
Controls.Add(UC3);
Controls.Add(UC4);
}
private void ShowUserControl1_Click(object sender, EventArgs e)
{
UC1.Visible = true;
UC2.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl2_Click(object sender, EventArgs e)
{
UC2.Visible = true;
UC1.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl3_Click(object sender, EventArgs e)
{
UC3.Visible = true;
UC1.Visible = false;
UC2.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl4_Click(object sender, EventArgs e)
{
UC4.Visible = true;
UC3.Visible = false;
UC2.Visible = false;
UC1.Visible = false;
}
}
You need to keep track of which user control was the previous in the page (and possible also the current, unless you want to iterate the UCs to find out). Use fields for this in the page.
public partial class Form1 : Form
{
UserControl[] userControls = new []{
new UserControl1(),
new UserControl2(),
new UserControl3(),
new UserControl4()
};
UserControl previous;
UserControl current;
public Form1()
{
InitializeComponent();
foreach(var uc in UserControls)
{
uc.Click += ShowPrevControl_Click;
Controls.Add(uc);
}
}
In the event (you only need one)
private void ShowUserControl_Click(object sender, EventArgs e)
{
foreach(UserControl uc in UserControls)
{
if(uc.Name == (string)((Control)sender).Tag)
{
previous = current;
uc.Visible = true;
current = uc;
}
else
{
uc.Visible = false;
}
}
}
private void ShowPrevControl_Click(object sender, EventArgs e)
{
if (previous != null)
{
foreach(var uc in UserControls)
{
uc.Visible = false;
}
var temp = current;
previous.Visible = true;
current = previous;
previous = temp;
}
}
Set the Tag property for each button to hold the name of the UserControl it should control (UserControl1, UserControl2, UserControl3 or UserControl4).
Let all the buttons click events be handled by ShowUserControl_Click.
Create a new public event in your user controls (if all should handle clicks), that that page can handle using your ShowPrevControl_Clickmethod:
public UserControlx : UserControl
{
public event EventHandler Click;
public UserControlx()
{
Button.Click += Button_Click;
}
private void Button_Click(object sender, EventArgs e)
{
if(Click != null)
Click(this, EventArgs.Empty);
}
}
An easy solution is to add a member variable to your class.
So your class would look like:
public partial class Form1 : Form
{
UserControl prevControl;
// Etc...
So when you click the button for, say, UC2, you can set prevControl to UC2.
private void ShowUserControl2_Click(object sender, EventArgs e)
{
UC2.Visible = true;
prevControl = UC2;
UC1.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
And on an event handler for the "Show previous control" button:
private void ShowPrevControl_Click(object sender, EventArgs e)
{
if (prevControl != null) prevControl.Visible = true;
}
UserControl is a reference in C#, which makes this possible.
string Path = #"C:\Users\Alexander\Desktop\Adressbok\Adressbok.txt";
List<string> sökhistorik;
//Lista
List<Person> Personer = new List<Person>();
//instans
Person p1 = new Person();
public Form1()
{
InitializeComponent();
}
private void updateUI()
{
lstBox.DataSource = null;
lstBox.DataSource = Personer;
}
private void btnSpara_Click(object sender, EventArgs e)
{
p1.Namn = tbxNamn.Text;
p1.Gatuadress = tbxGatuadress.Text;
p1.Postnummer = tbxPostnummer.Text;
p1.Postort = tbxPostort.Text;
p1.Telefonnummer = tbxTelefonnummer.Text;
p1.Epost = tbxEpost.Text;
Personer.Add(p1);
updateUI();
SaveToFile();
tbxNamn.Text = "";
tbxGatuadress.Text = "";
tbxPostnummer.Text = "";
tbxPostort.Text = "";
tbxTelefonnummer.Text = "";
tbxEpost.Text = "";
}
I want to edit the selected item from listbox and then edit the information and save it again and then make a delete button and delete the whole information. How do i do it. Im using windows forms c#.
Why don''t you use BindingList instead of List?
BindingList will automatically update your UI based on your source.
Assuming Person has a ToString(),
// Bind BindingList to Listbox
public class Form1 {
BindingList<Person> personer = new BindingList<Person>();
public Form1() {
InitializeComponent();
listBox1.DataSource = personer;
}
// Remove on button click
private void button1_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
//This automatically updates your listBox
personer.RemoveAt(listBox1.SelectedIndex);
}
}
// Update on Button click
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
Person p = personer[listBox1.SelectedIndex];
//Update person here
}
}
I have an event in my Form:
public void filterByType_TextChanged(object sender, EventArgs e)
{
dSearch = new D_Search(this);
dSearch.filterD(); }
which calls a function in another class. What I want to do is that I want to notice in my class which Textbox was altered and do something. So there are multiple functions like the one above and they all call the "filterD()" function in my DSearch class. I tried
if (sender == form1.filterByType_TextChanged)
{ sqlCmd = new SqlCommand("SELECT * FROM" } //SQL Statement
}
datTable = new DataTable();
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText,
connection);
sqlDatAdapter.Fill(datTable);
form1.setDataGrid = datTable;
but he can't find "sender" I also tried to create a new Button within the function in my Form and pass it but it doesn't seem to work.
try this -
In form 1
private void textBox1_TextChanged(object sender, EventArgs e)
{
var dSearch = new D_Search(this);
MessageBox.Show(dSearch.filterD(sender));
}
D_Search class
public class D_Search
{
Form1 frm = null;
public D_Search(Form1 frm1)
{
frm = frm1;
}
public string filterD(object sender)
{
string val = String.Empty;
if (sender == frm.textBox1)
{
val = (sender as TextBox).Text;
}
return val;
}
}
also if you want to access filterByType_TextChanged textbox in other class then change its modifier property to Internal
I am using SplitContainer tool in C# window application
I want to replace one Form for other form in splited Container panel
How can I do this?
I want to do in From From1 works finishes it work and show From2.. replace same place of splited container panel...
but this code not working...
public partial class Parent : Form{public Parent()
{
InitializeComponent();
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode node = treeView1.SelectedNode;
if (node.Text.ToString().Equals("Control1"))
{
//MessageBox.Show(node.ToString());
//Control1 conr1 = new Control1();
ShowForm(1);
}
else if (node.Text.ToString().Equals("Control2"))
{
//MessageBox.Show(node.ToString());
//Control2 conr2 = new Control2();
ShowForm(2);
}
}
public void ShowForm(int id)
{
Form childObj = null;
if (id == 1)
{
childObj = new Control1();
}
else
{
childObj = new Control2();
}
childObj.TopLevel = false;
childObj.Visible = true;
childObj.Parent = this.splitContainer1.Panel2;
this.splitContainer1.Panel2.Controls.Clear();
this.splitContainer1.Panel2.Hide();
this.splitContainer1.Panel2.Controls.Add(childObj);
this.splitContainer1.Panel2.Show();
childObj.Show();
}
public Control2()
{
InitializeComponent();
}
Parent bioAdMainForm = new Parent();
private void button1_Click(object sender, EventArgs e)
{
//Control1 enrollmentForm = new Control1();
//this.Hide();
//enrollmentForm.Show();
bioAdMainForm.ShowForm(1);
}
You can't place Form into Panel. Forms are intended to be displayed in separate window. You should use UserControl descendants instead of forms to achieve what you want.