Refresh a listbox's datasource - c#

I have a form for my update method, the form is in detail view. Next to the textboxes I have a listbox which shows the names of all the names in the database table. Under the listbox I also have an extra textbox to quick search the name in case user would like to type it in.
When I go to update one of the names, such as changing John to Jonathan, the database updates with the new name as I have checked on sql server, but the name in the listbox does not change! There's a dirty way to fix this by moving the position the listbox is selected on currently to movefirst(). However, under the listbox I have the textbox which is a quick search as I've mentioned, so I go to type Jonathan in the search text box, but nothing appears. However, if I type the former name John, then I get the details of this row in the table.
Is there a way I can fix this?
UPDATE 1:
Ive tried making the listbox datasource null then reassigning it again but it doesen't work. Ive put my code for my update form below.
namespace WindowsFormsApplication1
{
public partial class updateContact : Form
{
public updateContact()
{
InitializeComponent();
}
private void updateContact_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'tblcontactsupdate.tblContacts' table. You can move, or remove it, as needed.
this.tblContactsTableAdapter.Fill(this.tblcontactsupdate.tblContacts);
}
private void btnUpdateContact_Click(object sender, EventArgs e)
{
int x;
Program.da.UpdateCommand = new SqlCommand("Update tblContacts SET FIRSTNAME = #FIRSTNAME, LASTNME = #LASTNME WHERE ID = #ID", Program.cs);
Program.da.UpdateCommand.Parameters.Add("#FIRSTNAME", SqlDbType.VarChar).Value = fIRSTNAMETextBox.Text;
Program.da.UpdateCommand.Parameters.Add("#LASTNME", SqlDbType.VarChar).Value = lASTNMETextBox.Text;
Program.da.UpdateCommand.Parameters.Add("#ID", SqlDbType.VarChar).Value = iDTextBox.Text;
Program.cs.Open();
x = Program.da.UpdateCommand.ExecuteNonQuery();
Program.cs.Close();
if (x >= 1)
{
MessageBox.Show("Record(s) has been updated");
Program.ds.Clear();
Program.da.Fill(Program.ds);
txtfindUpdatecontact.Text = "";
//lbupdateContact.DataSource = null;
//lbupdateContact.DataSource = this.tblcontactsupdate.tblContacts;
}
}
private void txtfindUpdatecontact_TextChanged(object sender, EventArgs e)
{
if (!txtfindUpdatecontact.Text.Equals(""))
{
this.tblContactsBindingSource.Filter = "FIRSTNAME = '" + txtfindUpdatecontact.Text + "'";
}
else
{
this.tblContactsBindingSource.RemoveFilter();
}
}
private void lbupdateContact_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void iDTextBox_TextChanged(object sender, EventArgs e)
{
}
private void fIRSTNAMETextBox_TextChanged(object sender, EventArgs e)
{
}
private void lASTNMETextBox_TextChanged(object sender, EventArgs e)
{
}
}
}

You will have to set the DataSource of your listbox one more time after updating the source.
Something like below: It's my data:
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
public class MyDataSource
{
public static List<Person> Persons = new List<Person>
{
new Person{Age=30,Name="Ram"},
new Person{Age=33,Name="Rahim"},
};
}
then in the form's constructor you can do:
listBox1.DataSource = MyDataSource.Persons;
listBox1.DisplayMember = "Age";
then for updation, something like below:
private void button1_Click(object sender, EventArgs e)
{
MyDataSource.Persons[0].Age = 45;
listBox1.DataSource = null;
listBox1.DataSource = MyDataSource.Persons;
listBox1.DisplayMember = "Age";
}
This is just an example change code according to your need.

If your DataSource is a DataTable, all you have to do is calling AcceptChanges(), like this:
listBox.DataSource = null;
((DataTable)listBox.DataSource).AcceptChanges();

Related

Why after linking to Form the data doesn't transfer from Form2 to Form1

I am trying to do a big coding project however I hit a wall.
I need to show the name and score once the data has been entered in.
I tried using youtube tutorials, classes for the code. But no such luck.
Any help would be great!
form1:
private void bNew_Click(object sender, EventArgs e)
{
score link = new score();
link.Show();
SudentBox.Items.Clear();
}
form2:
public object StudentBox { get; private set; }
private void bCancel_Click(object sender, EventArgs e)
{
this.Close();
try
{
string name = txtName.Text;
int score = Convert.ToInt32(txtScore.Text);
txtStoreScores.Text += score.ToString() + " ";
}
catch (Exception x)
{
MessageBox.Show("Please enter a number");
}
}
private void bClearScores_Click(object sender, EventArgs e)
{
txtName.Text = "";
txtScore.Text = "";
txtStoreScores.Text = "";
}
Examples of what the forms should look like with the final result.
If I'm correct, you are trying to code a form of DialogBox.
Say, you want to get a name from the dialog (e.g. from a TextBox in Form2), you can have a model like this (in Form2 of course).
public string Name
{
//where myTextBox is the design name of your textbox
get => myTextBox.Text;
set => myTextBox.Text=value;
}
Simple Ok Button
public void OkBtnClick(object sender, EventArgs e)
{
this.Close();
}
Now, you need to actually get this info to display in your Form1. That is easy.
Just like you have started above:
private void bNew_Click(object sender, EventArgs e)
{
score link = new score();
link.ShowDialog();
//Note that you won't be able to access form1.
SudentBox.Items.Clear();
//You can now get the name
string _nameResult=link.Name;
NameTextbox.Text=_nameResult;
}
I hope this gets you started!
You do this by using the property.
Add public static property on Form 2 and set the values of the text to the property respectively and then access them on the Form 1.
On Form 2 in the Ok button click event do this
public static string Name { get; set; }
public static string Scores { get; set; }
private void bOk_Click(object sender, EventArgs e)
{
Name = txtName.Text;
Scores = txtStoreScores.TextBox;
}
Then in the Form 1 OnLoad event access those properties and display them in the TextBox
private Form1_Load (object sender, EventArgs e)
{
StudentBox.Items.Add(string.Format("{0} {1}", Form2.Name, Form2.Scores);
}

How to send Datagridview Values to Main form

I would like to send my Datagridview values to my Combobox in my mainform.
This is my code in my Datagridview form :
private void EquipmentList_Load(object sender, EventArgs e)
{
DataTable.RowCount = 30;
//Beam Description default value
DataTable.Rows[0].Cells[1].Value = "8.000m x 0.400m x 0.550m";
}
Below code is what i've used but nothing happened :
private void MainForm_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
EquipmentList ELform = new EquipmentList();
//Beam Combo Box default values
var BCBi1 = ELform.DataTable.Rows[0].Cells[1].Value.ToString();
this.BeamCB.Items.Add(BCBi1);
}
When i run it i'm getting this error:
error when running
An advance thank you for all those who will help me.
DataTable.Rows[0].Cells[1].Value is assigned in EquipmentList form when it is loaded.
EquipmentList ELform = new EquipmentList(); - here form is created but not loaded (you need to invoke Show or ShowDialog for that).
I suggest to declare publicly accessible default value (and not rely on existance of DataTable object with 1 row, which is a low-level implementation detail)
public const string DefaultSize = "8.000m x 0.400m x 0.550m";
private void EquipmentList_Load(object sender, EventArgs e)
{
DataTable.RowCount = 30;
DataTable.Rows[0].Cells[1].Value = DefaultSize;
}
and then
private void MainForm_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
this.BeamCB.Items.Add(EquipmentList.DefaultSize);
}
To the question "So is there any possible to load that values wihtout clicking/showing my equipmentlist form." Absolutely. Start by building a class for your data:
public class gridviewdata
{
public string content { get; set; }
public int row { get; set; }
public int cell { get; set; }
public gridviewdata(string content, int row, int cell)
{
this.content = content;
this.row = row;
this.cell = cell;
}
}
add a mediator class:
public static class mediator
{
public static List<gridviewdata> gridviewdatalist;
}
then add this code to your ELform load event:
private void EquipmentList_Load(object sender, EventArgs e)
{
DataTable.RowCount = 30;
//Beam Description default value
DataTable.Rows[0].Cells[1].Value = "8.000m x 0.400m x 0.550m";
mediator.gridviewdatalist.Add(new gridviewdata("8.000m x 0.400m x 0.550m", 0, 1);
}
then add a new method identifying your specific row to your MainForm:
private gridviewdata selectdata(int row, int cell)
{
foreach(gridviewdata data in mediator.gridviewdatalist)
{
if(data.row == row && data.cell == cell)
{
return data;
}
}
return null;
}
And finally call that code in your MainForm:
private void MainForm_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
//and call it there
var BCBi1 = selectdata(0, 1);
this.BeamCB.Items.Add(new Item(BCDi1, 1)); //Add value and index
}
Hope this helps.

Form Using User Control Won't Return Value

I am writing a user control. I want it to return a customer number when the user double clicks on the customer. I can't seem to get it to work. The user control is displayed and, on the double click, the data shows in the messagebox but I can't seem to get it to update the value on the main form.
Anytime I try to add a return value into FindCustomerControl_ItemHasBeenSelected, I get an error. It's like it hangs out in the user control and I can't leave it with a return value. So far, this is what I have:
In my main window:
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// one close button on the form
Close();
}
private void ShowSelectFromListWidget()
{
// show the user control
var uc = new FindCustomerControl();
uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
MakeUserControlPrimaryWindow(uc);
}
void uc_ItemHasBeenSelected(object sender,
FindCustomerControl.SelectedItemEventArgs e)
{
// once it has been selected, change a label on the screen to show the customer number
var value = e.SelectedChoice;
lblCustomer.Text = value;
}
}
In my user control:
public partial class FindCustomerControl : UserControl
{
public class SelectedItemEventArgs : EventArgs
{ public string SelectedChoice { get; set; } }
public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;
public FindCustomerControl()
{ InitializeComponent();}
DataTable dt = new DataTable();
public void btnFind_Click(object sender, EventArgs e)
{ var dt = GetData();
dataGridView1.DataSource = dt; }
//Query database
public DataTable GetData()
{
UtilitiesClass ru = new UtilitiesClass();
string connectionString = ru.getConnectionString();
DataTable dt = new DataTable();
SqlConnection myConnection = new SqlConnection(connectionString);
myConnection.Open();
SqlCommand cmd = new SqlCommand("FindCustomer", myConnection);
cmd.Parameters.AddWithValue("#customer", txtCustomer.Text.Trim());
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter ta = new SqlDataAdapter(cmd);
ta.Fill(dt);
myConnection.Close();
return (dt);
}
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
var handler = ItemHasBeenSelected;
string choice = dataGridView1[0, e.RowIndex].Value.ToString();
// this shows it
MessageBox.Show("Chosen: " + e.SelectedChoice);
if (handler != null) handler(this, new SelectedItemEventArgs { SelectedChoice = choice });
// I WOULD LIKE TO RETURN A VALUE HERE
}
}
It seems as though this should be common enough but, in spite of my hours of research and debugging, I have been unable to come up with a solution. I do know that uc.ItemHasBeenSelected += uc_ItemHasBeenSelected; in TestForm doesn't seem to ever get executed because I put a breakpoint there.
As I understood I guess you could use application current resources, where you can save any value you wish - in UWP it is something like this:
Application.Current.Resources["Name"] = customerNumber
Then you can cast this value to desired type:
(int)Application.Current.Resources["Name"]
Now you can use this value wherever you want.
Hope than helped in any way.
There is nothing wrong with the user class. It works fine. The problem is that the TestForm needs to start without the FindCustomerControl on it and instantiate the control within the program. It returns the value into the label or wherever else it needs to. Thanks very much to Brad Rem and this post: Return value from usercontrol after user action
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
ShowSelectFromListWidget();
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
private void ShowSelectFromListWidget()
{
var uc = new FindCustomerControl();
uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
this.MakeUserControlPrimaryWindow(uc);
}
void uc_ItemHasBeenSelected(object sender, FindCustomerControl.SelectedItemEventArgs e)
{
var value = e.SelectedChoice;
lblCustomer.Text = value;
lblMerchant.Focus();
//ClosePrimaryUserControl();
}
private void MakeUserControlPrimaryWindow(UserControl uc)
{
// my example just puts in in a panel, but for you
// put your special code here to handle your user control management
panel1.Controls.Add(uc);
}
private void ClosePrimaryUserControl()
{
// put your special code here to handle your user control management
panel1.Controls.Clear();
}
}

c# how to delete and edit information from selected in listbox?

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
}
}

Using next and previous buttons to navgiate through a list

So I am having some trouble with my C#forms. I have created a list of customers in which they have a there name, suburb, and bank account balances stored. Using a next and previous buttons I need to be able to allow the user to navigate through the current 5 objects in the list. How I was planning on doing so was when the user would click either the button, the text boxes would be filled with the relevant information. The reason why customer and other details are buttons is that later i need to be able to update the information stored in those fields, so i thought a good way to do that would be to erase what was already in the text box, type the new information, then press the button to update.
Anyways, my main issue is i need to use my view buttons to move through my list
This is how my form looks like:
My current form code is this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Customer c1 = new Customer("Sibel Yilmaz", "Wollongong", 2500, 3000, 5000);
Customer c2 = new Customer("John Doe", "Figtree", 2547, 2500, 3655);
Customer c3 = new Customer("Mariah Moore", "Coniston", 2500, 7000, 36000);
Customer c4 = new Customer("Jessica Blackshaw", "Bellambi", 3500, 6000, 4750);
Customer c5 = new Customer("Suzan Yilmaz", "Wollongong", 2500, 2000, 47110);
List<Customer> customers = new List<Customer>();
customers.Add(c1);
customers.Add(c2);
customers.Add(c3);
customers.Add(c4);
customers.Add(c5);
}
private void Form1_Load(object sender, EventArgs e) { }
private void button2_Click(object sender, EventArgs e) { }
private void button6_Click(object sender, EventArgs e) { }
private void textBox4_TextChanged(object sender, EventArgs e) { }
private void Customer_Click(object sender, EventArgs e) { }
}
And my Customer class is:
public class Customer
{
protected string name;
protected string suburb;
protected int postcode;
protected double credit_balance;
protected double saving_balance;
public Customer(string name, string suburb, int postcode, double credit_balance,
double saving_balance)
{
this.name = name;
this.suburb = suburb;
this.postcode = postcode;
this.credit_balance = credit_balance;
this.saving_balance = saving_balance;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Suburb
{
get { return suburb; }
set { suburb = value; }
}
public int Postcode
{
get { return postcode; }
set { postcode = value; }
}
public double Credit_Balance
{
get { return credit_balance; }
set { credit_balance = value; }
}
public double Savinig_Balance
{
get { return saving_balance; }
set { saving_balance = value; }
}
}
Please help me out, and let me know what the best way to go about this would be.
The first thing that you need to do is make your customers list have class level visibility so that you can access it in your button click events.
public partial class Form1 : Form
{
int index = 0;
List<Customer> customers = new List<Customer>();
public Form1()
{
... The remainder of your Constructor code
Once you do that you should be able to do something like this.
private void next_Click(object sender, EventArgs e)
{
if (index < customers.Count - 1)
{
index += 1;
textBox1.Text = customers[index].Name;
...
}
}
private void previous_Click(object sender, EventArgs e)
{
if (index > 0)
{
index -= 1;
textBox1.Text = customers[index].Name;
...
}
}
Using DataBinding ,and if you need to change the content of some field you could use the button to update or simply set the DataSourceUpdateMode as i do here to OnPropertyChange and every time you change the text in one of the textboxes it will update the datasource(in this case the List).You could define the Binding object seperatly then add it to the textbox.DataBindings so you could format and parse it,but here i just added them directly for demonstration purposes:
List<Customer> customers;
public Form1()
{
InitializeComponent();
//you could add the Customers directly to the add method of the list.
Customer c1 = new Customer("Sibel Yilmaz", "Wollongong", 2500, 3000, 5000);
Customer c2 = new Customer("John Doe", "Figtree", 2547, 2500, 3655);
Customer c3 = new Customer("Mariah Moore", "Coniston", 2500, 7000, 36000);
Customer c4 = new Customer("Jessica Blackshaw", "Bellambi", 3500, 6000, 4750);
Customer c5 = new Customer("Suzan Yilmaz", "Wollongong", 2500, 2000, 47110);
customers = new List<Customer>();
customers.Add(c1);
customers.Add(c2);
customers.Add(c3);
customers.Add(c4);
customers.Add(c5);
textBox1.DataBindings.Add("Text", customers, "Name",true,DataSourceUpdateMode.OnPropertyChanged);
textBox2.DataBindings.Add("Text", customers, "Suburb", true, DataSourceUpdateMode.OnPropertyChanged);
textBox3.DataBindings.Add("Text", customers, "Postcode", true, DataSourceUpdateMode.OnPropertyChanged);
textBox4.DataBindings.Add("Text", customers, "Credit_Balance", true, DataSourceUpdateMode.OnPropertyChanged);
textBox5.DataBindings.Add("Text", customers, "Savinig_Balance", true, DataSourceUpdateMode.OnPropertyChanged);
}
Then in your previous and next buttons:
private void PreviousBtn_Click(object sender, EventArgs e)
{
--this.BindingContext[this.customers].Position;
}
private void NextBtn_Click(object sender, EventArgs e)
{
++this.BindingContext[this.customers].Position;
}

Categories

Resources