In my code in POI class I want to implement some method, at first it will take data from .xls file.Then it will show city and population name in the datagridview table.Now from datagridview table it will take only the city name which will show in the 1st Combobox. Then if someone click on the 1st combobox item it will show some places in that city on the second combobox. However I wrote the code. Now I got puzzled how to call it from Form1.cs and how it will work, because at this moment it is not working at all.
My code for POI class is
public class POI
{
Form f;
public static ComboBox Combo_list1 = new ComboBox();
public static ComboBox Combo_list2 = new ComboBox();
public static DataGridView dataTable = new DataGridView();
Dictionary<string, List<string>> poi = new Dictionary<string, List<string>>();
public void List(Form f)
{
f = new Form();
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string SavedfileName = "POI_list.json";
var Saving_path = Path.Combine(folderName, SavedfileName);
string fileName = "Zensus_Gemeinden_org.xlsx";
var path = Path.Combine(startPath, fileName);
String name = "Gemeinden_31.12.2011_Vergleich";
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
path + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select [3] as City,[4] as Population, * From [" + name + "$D7:E11300] Where [4] > 10000", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
DataTable data = new DataTable();
sda.Fill(data);
dataTable.DataSource = data;
for (int i = 0; i < data.Rows.Count; i++)
{
Combo_list1.Items.Add(data.Rows[i]["City"]);
}
string Place_Json = "Place_List:" + JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText(Saving_path, Place_Json);
foreach(string line in File.ReadLines("POIList.txt"))
{
string[] parts = line.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
poi.Add(parts[0], new List<string>());
poi[parts[0]] = new List<string>(parts.Skip(1));
}
}
public void Combo_list_SelectedIndexChanged(object sender, EventArgs e)
{
if (Combo_list1.SelectedItem != null)
{
string txt = Combo_list1.SelectedItem.ToString();
if (poi.ContainsKey(txt))
{
List<string> points = poi[txt];
Combo_list2.Items.Clear();
Combo_list2.Items.AddRange(points.ToArray());
}
}
}
}
I want to call both method in my form1.cs class. but it is not working. Form1.cs look like this-
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
POI.Combo_list1 = comboBox1;
POI.dataTable = dataGridView1;
//POI.List();
//POI
}
private void button1_Click(object sender, EventArgs e)
{
}
}
sorry for such a long code.Answer is greatly appreciate.
in the way your code is currently written you need to instantiate a POI object in order to call those methods. you could either do that or make those methods static.
POI.List() of course will not work beacuse POI isn't an static class. Instead you should initialize a POI class object
POI instaceObj = new POI();
instanceObj.List();
Also I think that you should improve your code.
Hope this help.
Related
How to increase a variable every time I create a new Thread and store that value? I want to do mysqlbackup in each thread for different databases, and I will get the curBytes/totalBytes completed on Class1.cs. I want to update that value into datagridview.Row[iterate].Cell[2] simultaneously between threads where iterate corresponds with value 0 for first thread, 1 for second thread and so on.
I have tried using Interlocked.Increment and lock() but they seem not to work. I don't want to use BackgroundWorker.
This is the code that I haven't done anything to change datagridIterate (the value that iterate through datagridview Rows)
Form.cs:
private void button1_Click(object sender, EventArgs e)
{
restoreUI();
}
public void restoreUI()
{
mysqlUtils msu = new mysqlUtils();
foreach(DataGridViewRow row in dataGridView1.Rows)
{
Thread t = new Thread(() =>
{
msu.Restore(row.Cells[1].Value?.ToString(), server.Text, username.Text,
pwd.Text, row.Cells[0].Value?.ToString());
}
t.Start();
}
}
Class1.cs:
namespace Utils
{
public class mysqlUtils
{
public int total;
public int cur;
public void Restore(string filename, string server, string user,
string password, string db)
{
string constring = "server=" + server + ";user=" + user +
";pwd=" + password + ";database=" + db + ";";
string file = "C:\\Users\\SQL FILES\\" + filename;
using (MySqlConnection conn = new MySqlConnection(constring))
{
using (MySqlCommand cmd = new MySqlCommand())
{
using (MySqlBackup mb = new MySqlBackup(cmd))
{
cmd.Connection = conn;
conn.Open();
mb.ImportInfo.IntervalForProgressReport = 50;
mb.ImportProgressChanged += updateProgress;
mb.ImportFromFile(file);
conn.Close();
}
}
}
}
}
public void updateProgress(object sender, ImportProgressArgs e)
{
total = (int)e.TotalBytes;
cur = (int)e.CurrentBytes;
Form4 form4 = (Form4)Application.OpenForms[0];
form4.updateProgressValue(total, cur);
}
}
How should I manage to change datagridIterate that will have value i for first thread, i+1 for the next thread and so on? I would highly appreciate if you have any support.
Here's a big hint for your code that might help you to understand what you need.
Try this:
public class Form4 : Form
{
private DataGridView dataGridView1 = new DataGridView();
private TextBox server = new TextBox();
private TextBox username = new TextBox();
private TextBox pwd = new TextBox();
private void button1_Click(object sender, EventArgs e)
{
RestoreUI();
}
public void RestoreUI()
{
MySqlUtils msu = new MySqlUtils();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
string filename = row.Cells[1].Value?.ToString();
string s = server.Text;
string user = username.Text;
string password = pwd.Text;
string db = row.Cells[0].Value?.ToString();
Thread t = new Thread(() => msu.Restore(filename, s, user, password, db, UpdateProgress));
t.Start();
}
}
public void UpdateProgress(object sender, ImportProgressArgs e)
{
this.Invoke((Action)(() =>
{
/* add your code here to update the UI */
}));
}
}
And your MySqlUtils class.
public class MySqlUtils
{
public void Restore(string filename, string server, string user, string password, string db, ImportProgressChange updateProgress)
{
string constring = "server=" + server + ";user=" + user + ";pwd=" + password + ";database=" + db + ";";
string file = "C:\\Users\\SQL FILES\\" + filename;
using (MySqlConnection conn = new MySqlConnection(constring))
{
using (MySqlCommand cmd = new MySqlCommand())
{
using (MySqlBackup mb = new MySqlBackup(cmd))
{
cmd.Connection = conn;
conn.Open();
mb.ImportInfo.IntervalForProgressReport = 50;
mb.ImportProgressChanged += updateProgress;
mb.ImportFromFile(file);
conn.Close();
}
}
}
}
}
NB: I've changed the naming conventions to standard C#.
I'm trying to Iterate through rows in a 2 column table to check 1 field in each row against a Name. Once found I want to code to assign the corresponding Number to the OurNumber variable, and break out of the loop by setting GotTheNumber to true.
Below is the code I'm using:
private void BtnDelete_Click(object sender, EventArgs e)// Sends to ConfirmDeleteEMP Form
{
ConfirmDeleteEMP form = new ConfirmDeleteEMP();
DataTable table = new DataTable();
string connstring = #"Provider = Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\HoliPlanData.accdb;Persist Security Info=False";
using (OleDbConnection conn = new OleDbConnection(connstring))
{
string query = "SELECT PayrollNo, (FirstName + ' ' + LastName) AS NAME FROM [Employee]";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
adapter.Fill(table);
}
string SelectedName = DropBoxEmp.Text;
bool GotTheNumber = false;
int OurNumber = 0;
while (!GotTheNumber)
{
foreach (DataRow ThisRow in table.Rows)
{
if (SelectedName = (table.Rows[ThisRow]))
{
OurNumber = ///THATNUMBER///;
GotTheNumber = true;
}
}
}
MessageBox.Show(SelectedName);
var GoodNumber = (table.Rows[OurNumber]["PayrollNo"].ToString());
form.PassValueName = SelectedName;
form.PassSelectedPayroll = GoodNumber;
form.Tag = this;
form.Show(this);
Hide();
}
I don't know where to go from the If statement, so any help would be greatly appreciated.
Looping through the rows in your client program is exactly what you don't want to do. Let the database do that work for you. Try this:
private void BtnDelete_Click(object sender, EventArgs e)// Sends to ConfirmDeleteEMP Form
{
object result;
string query = "SELECT PayrollNo FROM [Employee] WHERE FirstName + ' ' + LastName = ?";
string connstring = #"Provider = Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\HoliPlanData.accdb;Persist Security Info=False";
using (OleDbConnection conn = new OleDbConnection(connstring))
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
//guessing at type and length here
cmd.Parameters.Add("?", OleDbType.VarWChar, 50).Value = DropBoxEmp.Text;
conn.Open();
result = cmd.ExecuteScalar();
}
if (result != null && result != DBNull.Value)
{
ConfirmDeleteEMP form = new ConfirmDeleteEMP();
form.PassValueName = DropBoxEmp.Text;
form.PassSelectedPayroll = (int)result;
form.Tag = this;
form.Show(this);
Hide();
}
}
If you really want to loop through the rows against all reason (it's slower, requires writing more code, and it's more error-prone), you can do this:
private void BtnDelete_Click(object sender, EventArgs e)// Sends to ConfirmDeleteEMP Form
{
DataTable table = new DataTable();
string query = "SELECT PayrollNo, (FirstName + ' ' + LastName) AS NAME FROM [Employee]";
string connstring = #"Provider = Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\\HoliPlanData.accdb;Persist Security Info=False";
using (OleDbConnection conn = new OleDbConnection(connstring))
{
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
adapter.Fill(table);
}
int PayrollNumber = 0;
foreach (DataRow ThisRow in table.Rows)
{
if (DropBoxEmp.Text == ThisRow["NAME"])
{
PayrollNumber = (int)ThisRow["PayrollNo"];
break;
}
}
//the whole loop could also be consolidated to this:
//PayrollNumber = (int)table.Rows.First(r => r["NAME"] == DropBoxEmp.Text)["PayrollNo"];
ConfirmDeleteEMP form = new ConfirmDeleteEMP();
form.PassValueName = DropBoxEmp.Text;
form.PassSelectedPayroll = PayrollNumber ;
form.Tag = this;
form.Show(this);
Hide();
}
Hm, hard to guess what exactly your problem is. But I think you just want to get the PayrollNo from the current row, aren't you?
Regarding the line further down ...
var GoodNumber = (table.Rows[OurNumber]["PayrollNo"].ToString());
... I think you could just call:
if (...)
{
OurNumber = ThisRow["PayrollNo"].ToString();
GotTheNumber = true;
}
However, I have no clue what you are doing with the following if-condition and if this really does what you want it to do:
if (SelectedName = (table.Rows[ThisRow]))
{
...
}
I got a large .xls file which contain many columns including city name population name etc.For my code purpose I only extract the city name and population number from this excell file. I made another class with a method which will do the modification of .xls file.Now in the main Form1.cs I want to show that value at first in datagridview table as two column Like city and population and then from datagridview I want to show the city name in combobox list. I wrote a code for this. But it is showing a lot of error.
To get the excel data I wrote the following code
public class Data
{
public string DataService(DataTable data)//showing error
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string SavedfileName = "POI_list.json";
var Saving_path = Path.Combine(folderName, SavedfileName);
string fileName = "Zensus_Gemeinden_org.xlsx";
var path = Path.Combine(startPath, fileName);
String name = "Gemeinden_31.12.2011_Vergleich";
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
path + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select [3] as City,[4] as Population, * From [" + name + "$D7:E11300] Where [4] > 10000", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
//DataTable data = new DataTable();
sda.Fill(data);
string Place_Json = "Place_List:" + JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText(Saving_path, Place_Json);
return data;//showing error
}
}
}
Now to get this value from main class in datagrid view and combobox I wrote following code
public partial class Form1 : Form
{
private readonly Data _DataService;// showing error
public Form1()
{
_DataService=new Data();
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
dataGridView1.DataSource = //here I want to set data from DataService method);
for (int i = 0; i < data.Rows.Count; i++)//showing error for 'for'
{
comboBox1.Items.Add(data.Rows[i]["City"]);
}
}
}
DataService method signature is public string DataService(DataTable data).
But you trying to return DataTable
EDIT:
Just modify your method:
public DataTable DataService()
{
var data = new DataTable();
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string SavedfileName = "POI_list.json";
var Saving_path = Path.Combine(folderName, SavedfileName);
string fileName = "Zensus_Gemeinden_org.xlsx";
var path = Path.Combine(startPath, fileName);
String name = "Gemeinden_31.12.2011_Vergleich";
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
path + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select [3] as City,[4] as Population, * From [" + name + "$D7:E11300] Where [4] > 10000", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
//DataTable data = new DataTable();
sda.Fill(data);
string Place_Json = "Place_List:" + JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText(Saving_path, Place_Json);
return data;
}
}
public partial class Form1 : Form
{
private readonly Data _data;
public Form1()
{
_data = new Data();
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var dataTable = _data.DataService()
dataGridView1.DataSource = dataTable ;
for (int i = 0; i < dataTable.Rows.Count; i++)//showing error for 'for'
{
comboBox1.Items.Add(dataTable.Rows[i]["City"]);
}
}
}
I implemented two Combobox in my coding. 1st combobox contain the city name and the 2nd combobox contain the POI of that city. Now I want to implement if else statement between this two combobox. Suppose if I select 1st combobox, Button will enable only for 1st one, then if I select 2nd Combobox then Button will work for 2nd one. I do not know how to do it. My code is like this
public void Download_Click(object sender, EventArgs e)
{
// if combox1 select
// all function will work for combobox 1
//else if combobox2 select
//combobbox1 disabled and all function will work for combobx2
}
Initially I created class to set the value of combobox1 like this
class PlaceList
{
public static ComboBox Combo_list = new ComboBox();
public static DataGridView dataTable = new DataGridView();
public static void List()
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string SavedfileName = "POI_list.json";
var Saving_path = Path.Combine(folderName, SavedfileName);
string fileName = "Zensus_Gemeinden_org.xlsx";
var path = Path.Combine(startPath, fileName);
String name = "Gemeinden_31.12.2011_Vergleich";
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
path + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select [3] as City,[4] as Population, * From [" + name + "$D7:E11300] Where [4] > 10000", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
DataTable data = new DataTable();
sda.Fill(data);
dataTable.DataSource = data;
for (int i = 0; i < data.Rows.Count; i++)
{
Combo_list.Items.Add(data.Rows[i]["City"]);
}
string Place_Json = "Place_List:" + JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText(Saving_path, Place_Json);
}
}
}
Then in Form1.cs I created
Dictionary<string, List<string>> poi = new Dictionary<string, List<string>>();
private void LoadKeys()
{
foreach (string line in File.ReadLines("TextFile1.txt"))
{
string[] parts = line.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
poi.Add(parts[0], new List<string>());
poi[parts[0]] = new List<string>(parts.Skip(1));
}
}
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
string txt = comboBox1.SelectedItem.ToString();
if (poi.ContainsKey(txt))
{
List<string> points = poi[txt];
comboBox2.Items.Clear();
comboBox2.Items.AddRange(points.ToArray());
}
}
}
That means combobox2 is dependent of combobox1. It will give the places name accoerding to the combobox1
then finally in form1.cs button 1 I am trying to do this somethis like this
public Form1()
{
InitializeComponent();
PlaceList.Combo_list = comboBox1;
PlaceList.List();
LoadKeys();
}
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex != 0)
{
ShortText.txt1 = richTextBox1;
ShortText.shortText(comboBox1.Text);
}
else if (comboBox2.SelectedIndex != 0)
{
ShortText.txt1 = richTextBox1;
ShortText.shortText(comboBox2.Text);
}
else
{
MessageBox.Show("Error");
}
Check the selected index of each combobox for the default value. The one that isn't the default value is the one you use. For example, if the default is index 0:
if(combo1.SelectedIndex != 0){
//do something
}
else if(combo2.SelectedIndex != 0) {
//do something else
}
else {
// Error: You need to select something!
}
i needed to create a form in which i hav to browse and open mdb files ---> i did this part usin oprnfile dialogue!
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog oDlg = new OpenFileDialog();
oDlg.Title = "Select MDB";
oDlg.Filter = "MDB (*.Mdb)|*.mdb";
oDlg.RestoreDirectory = true;
string dir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
oDlg.InitialDirectory = dir;
DialogResult result = oDlg.ShowDialog();
if (result == DialogResult.OK)
{
textBox1.Text = oDlg.FileName.ToString();
}
}
**this is my code so far!!!
now i need to make 3 list boxes!!
1st one to display the table names of the db!
2nd to to display field names when clicked on table name!!!
3rd to display attributes on fiels on clickin on it!
v can edit the attribute values and on clickin of save button it should update the database!!!
This class should get you the information you need.
public static class DatabaseInfoCollector
{
public static System.Collections.Generic.List<string> GetTables(string file)
{
System.Data.DataTable tables;
using(System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file))
{
connection.Open();
tables = connection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables,new object[]{null,null,null,"TABLE"});
}
System.Collections.Generic.List<string> Tables = new System.Collections.Generic.List<string>();
for (int i = 0; i < tables.Rows.Count; i++)
{
Tables.Add(tables.Rows[i][2].ToString());
}
return Tables;
}
public static System.Collections.Generic.List<string> GetColumnNames(string file, string table)
{
System.Data.DataTable dataSet = new System.Data.DataTable();
using(System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file))
{
connection.Open();
System.Data.OleDb.OleDbCommand Command = new System.Data.OleDb.OleDbCommand("SELECT * FROM " + table,connection);
using(System.Data.OleDb.OleDbDataAdapter dataAdapter = new System.Data.OleDb.OleDbDataAdapter(Command))
{
dataAdapter.Fill(dataSet);
}
}
System.Collections.Generic.List<string> columns = new System.Collections.Generic.List<string>();
for(int i = 0; i < dataSet.Columns.Count; i ++)
{
columns.Add(dataSet.Columns[i].ColumnName);
}
return columns;
}
}
Fill the tables list like this.
System.Collections.Generic.List<string> Tables = DatabaseInfoCollector.GetTables(textBox1.Text);
foreach(string table in Tables)
{
cboTable.Items.Add(table);
}
Fill the columns like this.
System.Collections.Generic.List<string> Columns = DatabaseInfoCollector.GetColumnNames(textBox1.Text,cboTable.SelectedItem.ToString());
foreach(string column in Columns)
{
cboColumns.Items.Add(column);
}
You can also use this method to return a DataTable containing all kinds of information about each column.
public static System.Data.DataTable GetSchemaData(string file)
{
System.Data.DataTable columns;
using(System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + file))
{
connection.Open();
columns = connection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Columns,new object[]{null,null,null,null});
}
return columns;
}
Use the System.Data.OleDb.* classes to get the data from the access file.
Example:
//Create the OleDbConnection object
//and associate it with our database
using(OleDbConnection conn = new OleDbConnection(
"PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source="+textBox1.Text)){
//Open the database connection
conn.Open();
//Create an OleDbCommand object and
//pass it the SQL read query and the connection to use
OleDbCommand cmd = new OleDbCommand(sqlstr,conn);
//Procure the OleDbDataReader object to browse the recordset
OleDbDataReader rdr = cmd.ExecuteReader();
//Keep reading records in the forward direction
while (rdr.Read())
{
//Use one of the various methods available to read the data
//Eg:- GetValue, GetValues, Item etc.
. . .
. . .
}
}
Use System.Data.OleDb to open a connection with new OleDbConnection(connectionString).
The connection string should be "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[PathToMDBFile]"
var conn = new OleDbConnection(connectionString);
var ds = new DataSet();
var adapter = new OleDbDataAdapter("SELECT Column1 FROM Table1", conn);
conn.Open();
adapter.Fill(ds);
conn.Close();
var value = ds.Tables[0].Rows[0]["Column1"].ToString();
That will get you the first value in the column named Column1