Auto Complete Textbox in database list value - c#

I've developed a simple system in C# MVC pattern, in model controller I have a list of employees. When the form loads, I want to add the list of employees to the textbox and user can filter the employee details by entering code and name of the employee. Now I don't know how to add employee list value to textbox auto complete customer source, please help..
Model controller
public List<Employee> Findlist()
{
List<Employee> emp = new List<Employee>();
string query = "select RTRIM(code) as [Code],RTRIM(name) as [Name] from m_Employee";
SqlCommand cmd = new SqlCommand(query);
cmd.Connection = con;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employee e = new Employee();
e.code = dr["code"].ToString();
e.name = dr["name"].ToString();
emp.Add(e);
}
dr.Close();
return emp;
}
Controller
public List<Employee> SearchEmp()
{
EmployeeModel md = new EmployeeModel();
return md.Findlist();
}
View
private void FrmEmployeeSearchBar_Load(object sender, EventArgs e)
{
try
{
LoginControll lc = new LoginControll();
List<Employee> emp = new List<Employee>();
emp = lc.SearchEmp();
AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
textBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
for (int i = 0; i < emp.Count; i++)
{
string result = Convert.ToString(emp[i].name);
//collection.Add(emp[i].code);
collection.Add(result);
}
textBox1.AutoCompleteCustomSource = collection;
//txtAutocompletesearcbar.au
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
}
}

Add the following lines
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
before
textBox1.AutoCompleteCustomSource = collection;

Related

Why is this code throwing 'System.ArgumentOutOfRangeException' (SQlite)?

I am having trouble understanding why I am getting this exception thrown !
This is the code :
public static List<Employee> LoadEmployees()
{
List<Employee> emp = new List<Employee>();
try
{
using (SQLiteConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
cnn.Open();
string query = "select * from Employee;";
SQLiteCommand cmd = new SQLiteCommand(query, cnn);
using (var reader = cmd.ExecuteReader())
{
int i = 0;
while (reader.Read())
{
emp[i].Id = reader.GetString(0);
emp[i].Name = reader.GetString(1);
emp[i].Gender = reader.GetString(2);
emp[i].Department = reader.GetString(3);
emp[i].Doj = reader.GetString(4);
emp[i].Email = reader.GetString(5);
emp[i].Phone = reader.GetString(6);
i++;
}
}
return emp;
}
}
catch (Exception ex)
{
emp = null;
return emp;
}
}
I tried debugging and found that -
id = 'emp[i].Id' threw an exception of type 'System.ArgumentOutOfRangeException'
Exception thrown: 'System.ArgumentOutOfRangeException' in mscorlib.dll
I am not understanding why it throwing it because i have initialized i = 0;
List<Employee> emp = new List<Employee>();
At this point, emp is empty, but you try accessing items by using emp[i] when it's still empty.
You should use emp.Add(new Employee()); at some point if you don't want the list to be empty anymore.
public static List<Employee> LoadEmployees()
{
List<Employee> emp = new List<Employee>(); // basically you have created new List<Employee> which is at the moment is empty. so if you try to do emp[0].Name, you will get exception
try
{
using (SQLiteConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
cnn.Open();
string query = "select * from Employee;"; // fetching employees from database
SQLiteCommand cmd = new SQLiteCommand(query, cnn);
using (var reader = cmd.ExecuteReader())
{
int i = 0;
while (reader.Read())
{
Employee e = new Employee(); // create new instance of employee object and initialize it's members and then add it in emp object.
e.Id = reader.GetString(0);
e.Name = reader.GetString(1);
e.Gender = reader.GetString(2);
e.Department = reader.GetString(3);
e.Doj = reader.GetString(4);
e.Email = reader.GetString(5);
e.Phone = reader.GetString(6);
emp.Add(e);
}
}
return emp;
}
}
catch (Exception ex)
{
emp = null;
return emp;
}
}

How to add the data coming from the datasource in the same row of the input data C#?

I hope I can explain this better but here is my dilemma.
When my form loads, it loads the employee name from my datasource in my combo box. I have two input text box for week and hours worked.
How it should work after clicking the Add button:
-dgv should populate the emp id in the column I created for the employee id, same with the name currently selected in the form as well as the week and the hours worked. However, it doesn't work that way because I am not sure how to add the Employee id that I should be getting from the datasource to the row I am creating when clicking Add. Please see below image.
Here is my code on the add button
Boolean blnsOK = true;
Decimal decValue = 0M;
lblError.Text = "";
//**Verify Payrate field is numeric.
try
{
decValue = Convert.ToDecimal(txtPayrate.Text);
}
catch (Exception ex)
{
lblError.Text = "Hours worked must be a numeric value";
blnsOK = false;
}
if (blnsOK)
{
//I am not sure what to put before the cboEmployee.text to pull the employee id from the datasource.
dtPay.Rows.Add(cboEmployee.Text,txtWeek.Text, txtPayrate.Text, decValue.ToString("N2"));
txtPayrate.Text = "";
}
Below is my code to display employees on form load.
lblError.Text = "";
dsData = clsDataBase.GetEmployeeNames();
if (dsData == null)
{
lblError.Text = "Error retrieving employee names";
}
else if (dsData.Tables.Count < 1)
{
lblError.Text = "Error retrieving employee names";
dsData.Dispose();
}
else
{
cboEmployee.DataSource = dsData.Tables[0];
cboEmployee.DisplayMember = "FullName";
}
Below is my code to get the data from the database
public static DataSet GetEmployeeNames()
{
SqlConnection cnSQL;
SqlCommand cmdSQL;
SqlDataAdapter daSQL;
DataSet dsSQL = null;
Boolean blnErrorOccured = false;
cnSQL = AcquireConnection();
if (cnSQL == null)
{
blnErrorOccured = true;
}
else
{
//**Build command to execute stored procedure
cmdSQL = new SqlCommand();
cmdSQL.Connection = cnSQL;
cmdSQL.CommandType = CommandType.StoredProcedure;
cmdSQL.CommandText = "GetEmployeeNames";
cmdSQL.Parameters.Add(new SqlParameter("#ErrCode", SqlDbType.Int));
cmdSQL.Parameters["#ErrCode"].Direction = ParameterDirection.ReturnValue;
dsSQL = new DataSet();
try
{
daSQL = new SqlDataAdapter(cmdSQL);
daSQL.Fill(dsSQL);
daSQL.Dispose();
}
catch (Exception ex)
{
blnErrorOccured = true;
dsSQL.Dispose();
}
finally
{
cmdSQL.Parameters.Clear();
cmdSQL.Dispose();
cnSQL.Close();
cnSQL.Dispose();
}
}
I appreciate your assistance and your patience.
add the Employee id that I should be getting from the datasource to the row I am creating when clicking Add
I don't see where you are adding rows to your DataGridView...However,it seems like you are filtering the data of your database and you just want to display the filtered data,am i correct ?
It is really unclear of what you want but here's a full example of what i understand of ur wants :
string column1;
string column2;
string column3;
SqlCommand cmd = new SqlCommand("Select * from TableName WHERE employeename='" + employee.Text + "'", connectionString);
SqlDataReader reader = cmd.ExecuteReader;
while (dr.read)
{
column2 = dr(1).ToString;
column3 = dr(2).ToString
}
column1 = employeename.Text;
DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = column1;
row.Cells[1].Value = column2;
row.Cells[2].Value = column3;
yourDataGridView.Rows.Add(row);

How to set first index as blank in combobox

I have a combobox that is bound with a datasource. In this combobox I have to add a blank field at index 0.
I have written following code for getting records.
public List<TBASubType> GetSubType(int typ)
{
using (var tr = session.BeginTransaction())
{
try
{
List<TBASubType> lstSubTypes = (from sbt in session.Query<TBASubType>()
where sbt.FType == typ
select sbt).ToList();
tr.Commit();
return lstSubTypes;
}
catch (Exception ex)
{
CusException cex = new CusException(ex);
cex.Write();
return null;
}
}
}
After this it bind with combobox with data binding source as below code.
M3.CM.BAL.CM CMobj = new M3.CM.BAL.CM(wSession.CreateSession());
lstSubTypes = CMobj.GetSubType(type);
this.tBASubTypeBindingSource.DataSource = lstSubTypes;
If you just want to select nothing initially, you can use
comboBox1.SelectedIndex=-1;
Thus you can't modify Items when you are are bound to DataSource, then only option to add blank row is modifying your data source. Create some empty object and add it to data source. E.g. if you have list of some Person entities bound to combobox:
var people = Builder<Person>.CreateListOfSize(10).Build().ToList();
people.Insert(0, new Person { Name = "" });
comboBox1.DisplayMember = "Name";
comboBox1.DataSource = people;
You can define static property Empty in your class:
public static readonly Person Empty = new Person { Name = "" };
And use it to insert default blank item:
people.Insert(0, Person.Empty);
This also will allow to check if selected item is default one:
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
Person person = (Person)comboBox.SelectedItem;
if (person == Person.Empty)
MessageBox.Show("Default item selected!");
}
cboCustomers.Items.Add(""); // Just add a blank item first
// Then load the records from the database
try
{
OleDbConnection con = new OleDbConnection(strDBConnection);
OleDbCommand cmd = new OleDbCommand();
con.Open();
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM Customers";
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
cboCustomers.Items.Add(dr["Name"]);
}
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
After creating my combo boxes, I added these lines to the end of the Load() method:
private void xyz_Load(object sender, EventArgs e)
{
this.xyzTableAdapter.Fill(this.DataSet.xyz);
this.comboBoxXYZ.SelectedIndex = -1;
}
replace xyz with the names you've given to your controls

How to show listbox item in textBox using data from local database in C#

Hi im new to programming and currently working on a project that lets a user enter its
registration data into a local database using textBoxes. The code works that its adding the items into the database
and after i press a "Show_users" button it displays them in the listBox_users listbox.
My problem is that when i choose a name from the listBox_users it should dislay the data about the selected user in the upper textBox'es i used to enter
the data in the first place using the event i created for the listBox_users,
but im getting an error that "can't read data from database that is already closed".
namespace Userform
{
public partial class Form1: Form
{
SqlCeDataReader rdr;
public Form1()
{
InitializeComponent();
}
// Some code between...
private void button_ShowUsers_Click(object sender, EventArgs e) //code that shows users in listBox
{
var dt = new DataTable();
string connectionString2 = #"Data Source=MyDatabase;Password=xxxxxx;";
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
var results = (from row in dt.AsEnumerable()
select new
{
//UserID = row.Field<int>("ID"),
FirstName = row.Field<string>("Firsname"),
LastName = row.Field<string>("Lastname"),
FullName = row.Field<string>("Firstname") + " " + row.Field<string>("Lastname")
}).ToList();
listBox_users.DataSource = results;
listBox_users.DisplayMember = "FullName";
rdr = cmd.ExecuteReader();
}
}
}
//I made an event for the listBox_users:
private void listBox_users_SelectedIndexChanged(object sender, EventArgs e)
//event code that should show listbox selected data in the textBoxes
{
if (listBox_inimesed.SelectedItem != null && rdr != null)
{
try
{
if (rdr.Read())
{
textBox1_firstname.Text = rdr.GetString(1);
textBox2_lastname.Text = rdr.GetString(2);
textBox3_email.Text = rdr.GetString(3);
textBox4_address.Text = rdr.GetString(4);
dateTimePicker1.Value = rdr.GetDateTime(5);
richTextBox_info.Text = rdr.GetString(6);
}
else MessageBox.Show("Object not found");
}
finally
{
rdr.Close();
}
}
}
}
The connection that the reader you are using is dependent on has been closed in the button_ShowUsers_Click event.
It is not a good practice to try to share connections and DataReaders across events. That will result in open connections that are not disposed of correctly. A better practice would be to have the creation of the Connection, Command, and DataReader take place in each event method. By using the "using" statement they will be closed and disposed of correctly in each method. You can also remove the class level variable "rdr".
namespace Userform
{
public partial class Form1 : Form
{
const string connectionString2 = #"Data Source=MyDatabase;Password=xxxxxx;";
public Form1()
{
InitializeComponent();
}
// Some code between...
private void button_ShowUsers_Click(object sender, EventArgs e) //code that shows users in listBox
{
var dt = new DataTable();
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
var results = (from row in dt.AsEnumerable()
select new
{
//UserID = row.Field<int>("ID"),
FirstName = row.Field<string>("Firsname"),
LastName = row.Field<string>("Lastname"),
FullName = row.Field<string>("Firstname") + " " + row.Field<string>("Lastname")
}).ToList();
listBox_users.DataSource = results;
listBox_users.DisplayMember = "FullName";
}
}
}
//I made an event for the listBox_users:
private void listBox_users_SelectedIndexChanged(object sender, EventArgs e)
//event code that should show listbox selected data in the textBoxes
{
if (listBox_inimesed.SelectedItem != null)
{
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
textBox1_firstname.Text = reader.GetString(1);
textBox2_lastname.Text = reader.GetString(2);
textBox3_email.Text = reader.GetString(3);
textBox4_address.Text = reader.GetString(4);
dateTimePicker1.Value = reader.GetDateTime(5);
richTextBox_info.Text = reader.GetString(6);
}
else MessageBox.Show("Object not found");
}
}
}
}
}
}

Reading Data from SQL DataBase Table to generic collection

I wanted to read all data from a table(containg 3 rows) and to add all the data into generic collection.From collection i wana bind to gridview.
The code displayed below works but only last row is displayed 3 times in gridview.Can You help me.Am a beginer
protected void Page_Load(object sender, EventArgs e)
{
List<Student> listid = new List<Student>();
Student stud = new Student();
SqlConnection con = new SqlConnection("........");
string sql = "select * from StudentInfo";
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}
GridView1.DataSource = listid;
GridView1.DataBind();
}
public class Student
{
private int studid;
public int Studid
{
get { return studid; }
set { studid = value; }
}
private string studName;
public string StudName
{
get { return studName; }
set { studName = value; }
}
private string studentDept;
public string StudentDept
{
get { return studentDept; }
set { studentDept = value; }
}
The output is like this:
You need to instantiate your object inside while loop
Otherwise you will have same data in the collection
So the code should be
protected void Page_Load(object sender, EventArgs e)
{
List<Student> listid = new List<Student>();
SqlConnection con = new SqlConnection("........");
string sql = "select * from StudentInfo";
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Student stud = new Student();
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}
GridView1.DataSource = listid;
GridView1.DataBind();
}
Also it is not a good practice to use while to data reader or directly open connection
You should use using statement.
using(SqlConnection con = new SqlConnection("connection string"))
{
con.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
In the DataReader while loop instantiate a new Student for each row in the database table:
while (dr.Read())
{
var stud = new Student();
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}

Categories