Calling a method from within a class - not working - c#

So I've got a class, commenter, and two methods within that class, SaveBtn_Click - created primarily not by me, and then also PeerReview, primarily created by me.
Anyway, the code starts off like this (after a variety of using statements):
public partial class commenter : System.Web.UI.Page
{
string employee_reviewed;
PeerReview pr = new PeerReview();
public void SaveBtn_Click(object sender, EventArgs e)
{
//all the information for the SaveBtn_Click method.
}
After that, I have PeerReview:
public void PeerReview(System.Web.UI.WebControls.ListBox listbox)
{
MySqlConnection con = new MySqlConnection("server=localhost;database=hourtracking;uid=username;password=password");
MySqlCommand cmd = new MySqlCommand("select first_name from employee where active_status=1", con);
con.Open();
MySqlDataReader r = cmd.ExecuteReader();
Console.WriteLine("Another test!");
Console.WriteLine(r);
Console.WriteLine("Hi, this is a test!");
while (r.Read())
{
listbox.Items.Add(new ListItem(Convert.ToString(r["first_name"]), Convert.ToString(r["first_name"])));
}
con.Close();
}
I'm connecting this with ASP.NET, and I can get the listbox to show up, but not the individual items in the listbox. I'm testing it with a console.writeline command, to see if that outputs anything - but nothing is being put out on the ASP page.
I'm not certain how I should reference these particular sections (new to C#, asking like 3 dozen questions about this).
ASP code looks like this:
<asp:ListBox ID="listBox1" runat="server">

You have some confused declarations.
You declare a method called PeerReview, but you also have an attempt to create an instance of PeerReview as though it were a type. I think you really just want to call the PeerReview method from your button click event, eg
public void SaveBtn_Click(object sender, EventArgs e)
{
PeerReview();
}
And then eliminate the "PeerReview pr = new PeerReview();" line. Also, as this is on a page, you have an implicit reference within the partial class to the listbox by its ID, so you don't need to pass it as a parameter. And the Console.WriteLines are not useful in a web application - you might try Response.Write if you're wanting to add that to the output for debug purposes.
Edits based on OP response
You should call PeerReview in the Page_Load event handler:
public void Page_Load(object sender, EventArgs e)
{
// You need to determine if you should call PeerReview every time the page
// loads, or only on the initial call of the page, thus determining whether
// you need the IsPostBack() test. My instinct is that you *do* want to constrain
// it to the first pass, but only you can make that determination for
// certain based on your requirements.
if (!Page.IsPostBack) //Do you need this check?
{
PeerReview();
}
}

You're trying to add items to listbox though your listBox has an id of listBox1
Rather than looping through your data and adding items why not bind the datasource to your listbox and then set the DataTextField and DataValueField on your listbox.
So for example (typos may exist..sorry.. been a while since i wrote C#)
MySqlConnection con = new MySqlConnection("server=localhost;database=hourtracking;uid=username;password=password");
MySqlCommand cmd = new MySqlCommand("select first_name from employee where active_status=1", con);
con.Open();
MySqlDataReader r = cmd.ExecuteReader();
listBox1.DataSource = r;
listBox1.DataBind();
con.Close();
If you can't bind to the reader (can't remember..) then dump your results into a datatable first, then bind to the listBox1
DataTable dTable = New DataTable();
dTable.Load(reader);
listBox1.DataSource = dTable;
listBox1.DataBind();
in your asp, set the listBox fields like:
<asp:ListBox ID="listBox1" runat="server" DataTextField="first_name" DataValueField="first_name">

quick view here is you are adding items to listbox instead of listBox1
change:
listbox.Items.Add(new ListItem(Convert.ToString(r["first_name"]), Convert.ToString(r["first_name"])));
to:
listBox1.Items.Add(new ListItem(Convert.ToString(r["first_name"]), Convert.ToString(r["first_name"])));

Related

Refresh datagridview from another user control

Using C# and Winform.
I read a couple of similar questions but couldn't find any great answers that could interlock with my code. So, bear with me and thank you in advance for helping me.
I have a single form that contains multiple User Controls. Inside the first user control, you can insert, update and delete records from the database. In the second User Control, there is a datagridview that is populated with all records.
The problem I have is that whenever I insert, update or delete a record inside the first user control. It won't refresh inside the datagridview when I swap to the second user control.
Beneath is the second user control that populates the datagridview
private void populate()
{
database.OpenConnection();
string query = "SELECT id, name, qoute, time, date from maintable";
SQLiteDataAdapter sda = new SQLiteDataAdapter(query, database.connection);
SQLiteCommandBuilder builder = new SQLiteCommandBuilder(sda);
var ds = new DataSet();
sda.Fill(ds);
dtgNav.DataSource = ds.Tables[0];
databas.CloseConnection();
}
private void Navigation_Load(object sender, EventArgs e)
{
populate();
dtgNav.Columns[0].HeaderText = "ID";
}
public void Refresh()
{
this.Refresh();
}
Beneath is the code for adding a record to the datagridview in the first user control
private void btnAdd_Click(object sender, EventArgs e)
{
database.OpenConnection();
string query = "INSERT INTO maintable (`id`, `name`, `qoute`, `time`,`date`) VALUES (#Id, #Name, #Qoute, #Time, #Date)";
SQLiteCommand command = new SQLiteCommand(query, database.connection);
command.Parameters.AddWithValue("#Id", tbxID.Text);
command.Parameters.AddWithValue("#Name", tbxName.Text.Trim());
command.Parameters.AddWithValue("#Qoute", tbxQoute.Text.Trim());
command.Parameters.AddWithValue("#Time", tbxTime.Text.Trim());
command.Parameters.AddWithValue("#Date", dtpDate.Value.ToString("yyyy-MM-dd"));
command.ExecuteNonQuery();
MessageBox.Show("Added new event into the database.");
database.CloseConnection();
usercontrol2.Refresh();
}
I would appreciate it if we found a way to refresh the datagridview when the button is clicked without changing the original code all too much.
You have a public void Refresh method in the second usercontrol, try modifying this.Refresh();, to say populate();. this should call your private void populate method that you called when loading which should reload the grid. Let me know if this helps.

How to store values before postback

I have two dropdownlists, ddlstates and ddlcitys.
The ddlstates has a list of Brazilian states that when clicked, loads the ddlcitys with the cities of that state. Until then, everything works correctly, but when clicking the save button which makes verification of completed fields or not, the ddlcitys back to the first option. How to store the information ddlcitys before the postback?
In code behind, have code that loads the ddlcitys:
protected void ddlstates_TextChanged(object sender, EventArgs e)
{
if (ddlstates.Text != "")
{
List<ListItem> cidades = new List<ListItem>();
SqlConnection conn = new SqlConnection(mytools.stringconection);
SqlDataReader dr = null;
conn.Open();
SqlCommand cmd = new SqlCommand("select ciddesc from cidades where cidestsigla = '" + ddlstates.SelectedValue.ToString() + "' order by 1 asc");
cmd.Connection = conn;
dr = cmd.ExecuteReader();
ddlcitys.Items.Clear();
while (dr.Read())
{
cidades.Add(new ListItem(dr[0].ToString()));
}
dr.Close();
conn.Close();
ddlcitys.DataTextField = "Text";
ddlcitys.DataValueField = "Value";
ddlcitys.DataSource = cidades;
ddlcitys.DataBind();
}
}
Asked long time ago, anyway may the answer help anyone.
On your page load event before bind any of your dropdownlists, make sure that not post back, then on your dropdown select change events , your dropdown values will not re bind so values will not changed.
hint : make sure that your aspx page enable view state (by default enabled) read more.
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
//this will called when your page loaded at first time, so bind your drop down values here.
} else {
//this will called on select change, don't bind your dropdown again, then values will be same (asp.net web forms viewstates will handle read more about viewstate).
}
}

ASP.NET why Gridview Paging on page 2 and the rest of it are disappear?

I have so many list of ServerName in GridView, so I decide to add paging. The data show list result on page 1 but on page 2 and the rest of it is not display anything. I already have OnPageIndexChanging="GridViewServer_PageIndexChanging" in GridViewServer property. Please help! Here is c# code behind,
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
GridViewServer.DataBind();
}
A GridView binding function codes,
public void BindGridView()
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Database_Shared_NotebookConnectionString"].ConnectionString);
conn.Open();
string sqlquery = ("SELECT * FROM tblServer");
SqlCommand command = new SqlCommand(sqlquery, conn);
SqlDataAdapter adp = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adp.Fill(ds);
GridViewServer.DataSource = ds.Tables[0];
GridViewServer.DataBind();
}
You need to set your GridView's datasource appropriately. You can't just call DataBind if the datasource isn't properly set. Basically what it amounts to is binding your GridView to null (which would have no page 2). I would recommend having a private method that is responsible for this process and whenever you need to bind you call that.
private void BindGridViewServer()
{
GridViewServer.DataSource = GetYourData(); // This should get the data
GridViewServer.DataBind();
}
Call this method from within your event with:
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
BindGridViewServer();
}
This could be made more extensible by passing in the GridView as a parameter, but you'd have to have other parameters as well to make sure the method retrieves the proper data.
Here's a very good tutorial (with sample code) on custom GridView paging. This makes the paging controls look like the familiar ones you see on a lot of search engines, forums, etc.
http://geekswithblogs.net/aghausman/archive/2009/05/18/custom-paging-in-grid-view.aspx
You have to give datasource to GridViewServer every time on page index changed.
so the code would be like this
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
GridViewServer.Datasource = MethodReturningDataTable();
GridViewServer.DataBind();
}

corrupt database & listbox problems

im working in WinForms C#.
for some reason when I want to populate my listBox it stops and says my database is corrupt.
I have added a repair line and the codes run afterwards, but nothing happends. My listbox is not populated.
Here is the code im using.:
public void button1_Click(object sender, EventArgs e)
{
SqlCeConnection cn = new SqlCeConnection(#"Data Source = Database1.mdf");
cn.Open();
SqlCeCommand cm = new SqlCeCommand("SELECT * FROM tblprojects ORDER BY Projekt_liste ASC", cn);
try
{
SqlCeDataReader dr = cm.ExecuteReader();
while (dr.Read())
{
ListBox project_list = Application.OpenForms["Form1"].Controls["tabControl1"].Controls["tabPage1"].Controls["Project_list"] as ListBox;
project_list.Items.Add(dr["Projekt_liste"].ToString());
}
cn.Close();
cn.Dispose();
}
catch (Exception ex)
{
}
}
public void button2_Click(object sender, EventArgs e)
{
SqlCeConnection cn = new SqlCeConnection();
SqlCeEngine engine = new SqlCeEngine("Data Source = Database1.mdf");
if (false == engine.Verify())
{
MessageBox.Show("Database is corrupted.");
engine.Repair(null, RepairOption.RecoverAllPossibleRows);
}
}
For example if you want to load the items
1. make sure you have a ListBox on the winform
2. name the ListBox
3. Create a ListItem
4 Add the ListItem to the ListBox
while(dr.Read())
{
ListViewItem obj=new ListViewItem(Convert.ToString(dr[0]),Convert.ToString(dr[1]);
//in object of ListViewItem give display member at first and give value member at second position
listView1.Items.Add(obj); // add object to the listbox
}
Here are a few links that you can use as well to show different ways on how to populate a ListBox
one is Windows and the other will be if you are using or plan to use ASP.NET
Populate a ListBox when using SQLDataReader
asp.net SqlDataReader example: how to use Read() method to populate ListBox
Populate ASP.NET ListBox using SqlDataReader
From Microsoft Site
The Repair method does not guarantee complete data recovery for every
database. Some forms of data corruptions cannot be repaired
completely, regardless of the Repair option that is selected by the
application.
This could be one of the case where your file is corrupted.
Also please try To have repair call straight above the call to populate Data in List.
This may help.

I cant see new element in Datagridview without restart

I have added a record to the underlying db and after I add the record i do a
datagridview.Refresh(); and i dont see the newly added record.
If i stop and start the application its there. What am I doing or not
doing?
Notes : button1 and datagridview is in different Forms.I made datagridview's Modifiers public. This project is ado.net project
public class CustomerService
{
public List<Customers> ShowAll()
{
List<Customers> customers = new List<Customers>();
SqlConnection conn = new SqlConnection("data source=.; database=custer; user id=sa; password=*****");
SqlCommand cmd = new SqlCommand(" select * from Customers ", conn.Open());
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Customer customer = new Customer ()
{
CustomerID = dr.GetInt32(0),
CustomerName = dr.GetString(1),
CustomerSurname = dr.GetString(2),
};
customers.Add(customer);
}
conn.Close();
return customers;
}
}
private void button1_Click(object sender, EventArgs e)
{
CustomerService service = new CustomerService();
if (txtCustomerName.Text != "" || txtCustomerSurname.Text != "")
{
customerservice.customerAdd(txtCustomerName.Text, txtCustomerSurname.Text);//this rows is other method .I am using for adding new customer
MessageBox.Show("Customer Added");
Form1.dataGridView1.DataSource = service.ShowAll();
Form1.dataGridView1.Refresh();
}
else
{
//……………
}
}
After adding the data to the DB, your application knows nothing about the data added. You need to load those data to memory. Retrieve all the data you want to display from the database and bind it explicitly to UI after doing operations on database.
EDIT:
Can you check what ShowAll() returns while debugging? Does it return you the data you actually want?
If it is a WPF application take a look here. The issue here is to tell your UI component that underlying data source has been changed, so the UI component reflects the changes made to data.
Again if it is a WPF application, you can define your data as ObservableCollection and bind you UI to this collection. ObservableCollection automatically requests UI to refresh when data has changed.
Rica ederim .)
The usual way of doing this is to reset the DataSource of the DataGridView.
Try like this code (with correct code to provide the right datasource):
Form1.dataGridView1.DataSource = typeof(List);
Form1.dataGridView1.DataSource = service.ShowAll();
Calling .Refresh() doesn't work since it only forces a repaint, but the code that paints the grid doesn't know of the changes.
Ref this WPF link also, that may help you:
Why does the DataGrid not update when the ItemsSource is changed?
Try calling EndEdit on the datagridview:
this.dataGridView1.EndEdit();
Second, refresh the grid view:
this.dataGridView1.Refresh();
And if that still doesn't work, try calling Refresh on the containing control
ParentControl.Refresh()
This will end up calling a repaint that might be needed.
what is the content of customerservice.customerAdd ?
Maybe it doesnt close the connection properly/doesnt flush the data into the db,and it only happens when you close your app(all memory is disposed,and all connections are closed/flushed).
Also - I suggest using a BindingSource that the grid is bound to,and changing its data source - it has event to notify the grid automaticallly if its data source has changed and that will cause it to refresh.
As you said these are in different forms, I think the pointer to Form1 doesn't point to the form that you want. you should pass the pointer of that form with this to this form.
When you are creating form 2 define like this:
Form2 = new Form2();
Form2.form1 = this;
Then your code should work.
It appears you're using a List as the datasource. I've found using a generic list is ok for read only data but for doing any kind of updates you need something with more power. I don't know about WPF but in winForms I've had great success with the IBindingList interface and the BindingList generic collection. The BindingList generic collection implements the IBindingList interface for you. I would read the MSDN articles on both of them. I've pretty much stopped using the IBindingList interface but it's still perfectly fine to implement.
http://msdn.microsoft.com/en-us/library/system.componentmodel.ibindinglist.aspx
http://msdn.microsoft.com/en-us/library/ms132679.aspx
The answer is to have the gridview connected to the BindingList<Customers> rather than the List<Customers> . Hope this will solve your problem...
If you change the List to a BindingList you'll have success. I threw together a sample which just had a DataGridView and a couple of Buttons on a Form.
button1 generates some fake data and assigns the datasource.
button2 adds another Customer to the underlying list.
The DataGridView is updated when the underlying BindingList changes.
Code:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string SurName { get; set; }
}
public partial class Form1 : Form
{
BindingList<Customer> customers = new BindingList<Customer>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; ++i)
{
customers.Add(new Customer
{
Id = i,
Name = "Name" + i,
SurName = "Surname" + i
});
}
dataGridView1.DataSource = customers;
}
private void button2_Click(object sender, EventArgs e)
{
customers.Add(new Customer
{
Id = 22,
Name = "Newname",
SurName = "Newsurname"
});
}
}
Now, the reason this works is that BindingList<T> implements IBindingList, among other things, and that interface has, among other things, an event called ListChanged which is raised when the list or something in the list changes.
If you are not bound to use customer list strictly as data-source for datagridview then
Here is much better solution using datatable. You will get updated customer list and datagridview after insert
public class CustomerService
{
public DataTable ShowCustomers()
{
string cns = "data source=.; database=custer; user id=sa; password=*****";
SqlConnection conn = new SqlConnection(cns);
SqlDataAdapter da = new SqDataAdapter("select * from Customers", conn);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
private void button1_Click(object sender, EventArgs e)
{
CustomerService service = new CustomerService();
if (txtCustomerName.Text != "" || txtCustomerSurname.Text != "")
{
customerservice.customerAdd(txtCustomerName.Text,txtCustomerSurname.Text);
MessageBox.Show("Customer Added");
DataTable dt = service.ShowCustomers();
Form1.dataGridView1.DataSource = dt;
//If you also need customer list. Provide the DataTable and get list
List<Customers> customers = new List<Customers>();
for (int i=0;i<dt.Rows.Count;i++)
{
Customer customer = new Customer();
customer.CustomerID = Convert.ToInt32(dt.Rows[i][0]);
customer.CustomerName = dt.Rows[i][1].ToString();
customer.CustomerSurname = dt.Rows[i][2].ToString();
customers.Add(customer);
}
}
}
You need to do data binding only once not on every new record. That's the whole point of binding data to a control that all changes will be auto reflected.
Make customers a data member of the CustomerService class and change your code appropriately:
class CustomerService {
List<Customers> customers;
...
}
Next the binding code should be done once, maybe when the first record is added to the List<Customers>.
BindingSource binding = new BindingSource();
binding.DataSource = customers;
dataGridView1.DataSource = binding;
If you have done this right, every time any record is deleted or added to the customers collection, it should be automatically be reflected in the DataGridView control.
I think you must have used update panel and might not refreshing that
I think this will solve your problem, Check this........
DataGrid.CommitEdit();
DataGrid.Items.Refresh();
NOTE
CommitEdit() method will fire the RowEditEnding event, it is a endless loop. WPF does not allow to refresh the view while it is editing, since it may occur the endless loop. However, you could refresh the view after editing. Try to remove the RowEditEnding event handler (If Initialzed) , and do refresh for the Items; Then add the event handler back:

Categories

Resources