I am adding records to my database via a windows form. But when ever I add a new record it doesnt update until I close the app and then start again. Even though I think I am telling it to update (Im obv not!!)
Do I need a new varibale to update the database? Im a little stuck.
EDIT: All code on this..
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
namespace MediaManagementSystem
{
public partial class AddMedia : Form
{
//database var
OleDbConnection m_cnADONetConnection = new OleDbConnection();
OleDbDataAdapter m_daDataAdapter;
OleDbDataAdapter m_cbCommandBuilder;
DataTable m_dtMedia = new DataTable();
int m_rowPosition = 0;
public AddMedia()
{
InitializeComponent();
}
private void BrowseButton_Click(object sender, EventArgs e)
{
//load up file dialog and find media
if (addFileDialog.ShowDialog() == DialogResult.OK)
{
//add media file name to file path text box
txtFilePath.Text = addFileDialog.FileName;
}
}
private void CancelButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void AddButton_Click(object sender, EventArgs e)
{
//add the new record to the database
DataRow drNewRow = m_dtMedia.NewRow();
drNewRow["FilePath"] = txtFilePath.Text;
drNewRow["Subject"] = txtSubject.Text;
drNewRow["Title"] = txtTitle.Text;
drNewRow["Keywords"] = txtKeywords.Text;
drNewRow["MediaType"] = AddComboBox.Text;
m_dtMedia.Rows.Add(drNewRow);
m_daDataAdapter.Update(m_dtMedia);
m_rowPosition = m_dtMedia.Rows.Count - 1;
this.ShowCurrentRecord();
this.Close();
}
private void AddMedia_Load(object sender, EventArgs e)
{
//link to the database and conect to database
m_cnADONetConnection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Max\Documents\Visual Studio 2010\Projects\MediaManagementSystem\MediaManagementSystem\bin\Debug\MediaDB.mdb";
m_cnADONetConnection.Open();
OleDbConnection objConnection = new OleDbConnection(m_cnADONetConnection.ConnectionString);
m_daDataAdapter = new OleDbDataAdapter("Select * From Media", m_cnADONetConnection);
OleDbCommandBuilder m_cbCommandBuilder = new OleDbCommandBuilder(m_daDataAdapter);
m_daDataAdapter.Fill(m_dtMedia);
m_daDataAdapter.Update(m_dtMedia);
}
public void ShowCurrentRecord()
{
m_daDataAdapter.Update(m_dtMedia);
if (m_dtMedia.Rows.Count == 0)
{
txtFilePath.Text = "";
txtSubject.Text = "";
txtTitle.Text = "";
txtKeywords.Text = "";
AddComboBox.Text = "";
return;
}
txtFilePath.Text = m_dtMedia.Rows[m_rowPosition]["FilePath"].ToString();
txtSubject.Text = m_dtMedia.Rows[m_rowPosition]["Subject"].ToString();
txtTitle.Text = m_dtMedia.Rows[m_rowPosition]["Title"].ToString();
txtKeywords.Text = m_dtMedia.Rows[m_rowPosition]["Keywords"].ToString();
AddComboBox.Text = m_dtMedia.Rows[m_rowPosition]["MediaType"].ToString();
}
}
}
It would best if you use DataSet and then update the records in it. Finally you need to call AcceptChanges() after the update() command to commit the changes with dataset something as below also reload the data after to enter to get the recent data info:
dataset.AcceptChanges()
After you open AddMedia form from your MAIN form, you need to RALOAD all your records again. Look how the form is doing it when it opens and do the same AFTER you open your AddMedia form ;)
Related
Every time when I click the button only one row will be displayed. But it should show multiple rows. I declare the list after the constructor invoke. I tried with gridview.update() and gridview.refresh() but they didn't work. I could not findout the issue.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using JournalEntryApp.Model;
namespace JournalEntryApp
{
public partial class NewDocument : Form
{
public NewDocument()
{
InitializeComponent();
}
List<JEFrom> JEFromsList = new List<JEFrom>();
List<JETo> JETosList = new List<JETo>();
JEFrom _jef = null;
private void NewDocument_Load(object sender, EventArgs e)
{
label4.Text = DateTime.Now.ToString("dd-MMM-yyyy");
using (var db =new JournalContext())
{
unitComboBox.DataSource = db.Units.ToList();
unitComboBox.ValueMember = "Id";
unitComboBox.DisplayMember = "UnitName";
}
}
private void addToListButton_Click(object sender, EventArgs e)
{
if (string.Empty== fromAccountTextBox.Text)
{
MessageBox.Show("From Account can not be empty!!!");
}
else if (string.Empty == toAccountTextBox.Text)
{
MessageBox.Show("To Account can not be empty!!!");
}
else
{
_jef = new JEFrom{ FromEntryName= fromAccountTextBox.Text , FromEntryDate= DateTime.Now };
JEFromsList.Add(_jef);
temporaryDataGridView.DataSource = JEFromsList;
fromAccountTextBox.Text = string.Empty;
toAccountTextBox.Text = string.Empty;
}
}
}
}
The temporaryDataGridView cannot detect that you have changed the DataSource. It will only refresh when Datasource has changed.
temporaryDataGridView.DataSource = null;
temporaryDataGridView.DataSource = JEFromsList;
so change the Datasource null first.
Or you can use bindingSource
private void NewDocument_Load(object sender, EventArgs e)
{
this.bindingSource1.DataSource = JEFromsList;
temporaryDataGridView.DataSource = this.bindingSource1;
label4.Text = DateTime.Now.ToString("dd-MMM-yyyy");
using (var db =new JournalContext())
{
unitComboBox.DataSource = db.Units.ToList();
unitComboBox.ValueMember = "Id";
unitComboBox.DisplayMember = "UnitName";
}
}
in button_click
JEFromsList.Add(_jef);
bindingSource1.ResetBindings(true);
I have a form which is running on the other laptop, this is the kitchen side where all the orders will go through after buying in my POS (which is running on the other laptop also) side.
Now my listview in the kitchen side refreshes after 5 seconds 'using the timer', are there any options or ways to refresh the listview without using the timer so that the 'Focus' when I select an item inside the listview will not disappear?
This is the my code:
public Kitchen()
{
InitializeComponent();
listView2.Columns.Add("ORDERS", 800);
listView2.View = View.Details;
System.Windows.Forms.Timer timer_1 = new System.Windows.Forms.Timer();
timer1.Interval = 5000;
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();
}
private void dinein(String tblnmber)
{
String[] row = { tblnmber };
listView2.Items.Add(new ListViewItem(row));
}
public void loaddinein()
{
listView2.Items.Clear();
string sq = "select tblnmber as [ORDERS] FROM Kitchen Group By tblnmber";
cmd = new SqlCommand(sq,con);
try
{
con.Open();
adp = new SqlDataAdapter(cmd);
adp.Fill(dt);
foreach (DataRow row in dt.Rows)
{
dinein(row[0].ToString());
}
con.Close();
dt.Rows.Clear();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
con.Close();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
loaddinein();
}
Well your question is really how do I refresh an existing list of items without changing order or focus? not anything to do with timers.
To accomplish that when you fetch the data from the DB again, you need to determine which items have changed in the list (compare the text of your model to an item in the list) and simply update the Text of those items. Overwriting a ListViewItem's Text property won't change selection/focus or re-ordering by default.
Don't clear out the ListView and repopulate otherwise focus/selection will change.
A timer is still perfectly valid to use.
Pooling continuously to the DB server is not a good approach, you can go for either of the two approaches.
Raise a change message using trigger to MSMQ, and subscribe to the
MSMQ for new messages. For more details on the implementation you
can check here
Monitoring the data changes using SqlDependency, for more details you can check here
Note: Both the approaches have it own pro/cons. For example if the number of listeners are more, in that case SQL Dependency will hit the performance.
Hi guys i've already watch and read some tutorials , and implement it, unfortunately sql dependency is not firing to my datagridview nor listview. I've also enabled the broker.
This is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
//ALTER DATABASE HOB SET ENABLE BROKER
namespace DemoSQL
{
public partial class Form1 : Form
{
public string m_connect = #"Data Source=DESKTOP-3B561M1;Initial Catalog=Users;Integrated Security=True";
SqlConnection con = null;
public delegate void NewHome();
public event NewHome OnNewHome;
public Form1()
{
InitializeComponent();
try
{
SqlClientPermission ss = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
ss.Demand();
}
catch (Exception)
{
throw;
}
SqlDependency.Stop(m_connect);
SqlDependency.Start(m_connect);
con = new SqlConnection(m_connect);
}
private void Form1_Load(object sender, EventArgs e)
{
OnNewHome+=new NewHome(Form1_OnNewHome);//tab
//load data vao datagrid
LoadData();
}
public void Form1_OnNewHome()
{
ISynchronizeInvoke i = (ISynchronizeInvoke)this;
if (i.InvokeRequired)//tab
{
NewHome dd = new NewHome(Form1_OnNewHome);
i.BeginInvoke(dd, null);
return;
}
LoadData();
}
//Ham load data
void LoadData()
{
DataTable dt = new DataTable();
if (con.State==ConnectionState.Closed)
{
con.Open();
}
SqlCommand cmd = new SqlCommand("SELECT FirstName,LastName from dbo.Uss", con);
cmd.Notification = null;
SqlDependency de = new SqlDependency(cmd);
de.OnChange += new OnChangeEventHandler(de_OnChange);
dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));
dataGridView1.DataSource = dt;
}
public void de_OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency de = sender as SqlDependency;
de.OnChange -= de_OnChange;
if (OnNewHome!=null)
{
OnNewHome();
}
}
}
}
where is the problem with this code? When i start the program there is no values to choose from comboBox. There is no problems with compiling and starting an application. I have no idea what is wrong here. Maybe someone have solution for this problem.
Link to pastebin https://pastebin.com/pASVNWq
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace parKing_new
{
public partial class editClient : Form
{
public editClient()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{}
//Load customer ID to a combobox
private void LoadCustomersId()
{
var connectionString =
"Server=localhost;Port=3306;Database=ewisys;Uid=root;password=;";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
var query = "SELECT clientID FROM clients";
using (var command = new MySqlCommand(query, connection))
{
using (var reader = command.ExecuteReader())
{
//Iterate through the rows and add it to the
combobox's items
while (reader.Read())
{
comboBox1.Items.Add(reader.GetString("clientID"));
}
}
}
}
}
//Load customer details using the ID
private void LoadCustomerDetailsById(int id)
{
var connectionString =
"Server=localhost;Port=3306;Database=ewisys;Uid=root;password=;";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
var query = "SELECT clientID, name, surName FROM clients WHERE
Id = #clientID";
using (var command = new MySqlCommand(query, connection))
{
//Always use SQL parameters to avoid SQL injection and it
automatically escapes characters
command.Parameters.AddWithValue("#clientID", id);
using (var reader = command.ExecuteReader())
{
//No customer found by supplied ID
if (!reader.HasRows)
return;
ClientIDTextBox.Text =
reader.GetInt32("clientID").ToString();
nameTextBox.Text = reader.GetString("name");
surNameTextBox.Text = reader.GetString("surName");
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var clientID = Convert.ToInt32(comboBox1.Text);
LoadCustomerDetailsById(clientID);
}
}
}
Add this to your code.
The reason behind this is that when you launch your application, nothing is calling LoadCustomersId() function to populate the data on your comboBox. So use the Load event handler and populate your combobox from there:
private void editClient_Load(object sender, EventArgs e)
{
LoadCustomersId();
}
I think you have only defined LoadCustomersId() method, but you are not calling it from anywhere.you need to call the method
I want to write an windows form application who can do auto data filling in an textbox on the web page and get the corresponding data show on the page one by one. I met a problem that my loop goes too fast and I cannot see the result showing on the page. How can I let the page fully loaded and then go the next loop?
My designer has a textbox which is used to input url, webBrowser to browse the web page, the button is used to lunch the page.
My code are as below. I use "http://finance.yahoo.com/" as testing page. Testing data is in excel format. the data is a row, like " msft, bac, f, aapl".
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Net;
using System.IO;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string url = textBox1.Text;
var request = (HttpWebRequest)WebRequest.Create(url);
var response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
webBrowser1.DocumentText = content;
}
public void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlElement tbUserid = webBrowser1.Document.GetElementById("mnp-search_box");
//HtmlElement tbPasswd = webBrowser1.Document.GetElementById("pwdInput");
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("yucs-sprop_button");
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
if (tbUserid == null || btnSubmit == null)
{
return;
}
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='d:\\testing file\\list.xls';Extended Properties= \"Excel 8.0;HDR=Yes;IMEX=1\";");
OleDbDataAdapter da = new OleDbDataAdapter("select * from [List$]", con);
DataTable dt = new DataTable();
da.Fill(dt);
/* int i = 0;
do
{
string str = dt.Rows[i][0].ToString();
tbUserid.SetAttribute("value", str);
//System.Threading.Thread.Sleep(10000);
btnSubmit.InvokeMember("click");
evt.WaitOne();
i++;
}
while (i < dt.Rows.Count);
*/
for (int i = 0; i < dt.Rows.Count; i++)
{
string str = dt.Rows[i][0].ToString();
tbUserid.SetAttribute("value", str);
btnSubmit.InvokeMember("click");
Application.DoEvents();
//System.Threading.Thread.Sleep(100);
}
// ((WebBrowser)sender).Dispose();
}
}
}
Ok, so, let's suppose your target page is http://thisis.my/addres.html and when the page has been used to insert a row it redirects to http://thisis.my/secondaddres.html.
First, let's create a List to hold all the data from the table and two strings to hold the concrete addresses:
List<string> rows = new List<string>();
static string fillAddress = "http://thisis.my/addres.html";
static string sentAddress = "http://thisis.my/secondaddres.html";
Second, when the button is pressed load the data in the list and do your first navigation:
private void button1_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='d:\\testing file\\list.xls';Extended Properties= \"Excel 8.0;HDR=Yes;IMEX=1\";");
OleDbDataAdapter da = new OleDbDataAdapter("select * from [List$]", con);
DataTable dt = new DataTable();
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
string str = dt.Rows[i][0].ToString();
rows.Add(str);
}
webBrowser1.NavigateTo(fillAddress);
}
Ensure that your DocumentCompleted event is hooked thorugh designer or code.
And finally when a document has been fully loaded the do this sequence:
If page == fillAddress
If rows is not empty
Extract row
Fill row
Submit
else
We have finished
else
Navigate to fillAddress
-
public async void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if(e.Url.ToString() == fillAddress)
{
if(rows.Count > 0)
{
HtmlElement tbUserid = webBrowser1.Document.GetElementById("mnp-search_box");
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("yucs-sprop_button");
if (tbUserid == null || btnSubmit == null)
return;
string str = rows[0];
rows.RemoveAt(0);
tbUserid.SetAttribute("value", str);
btnSubmit.InvokeMember("click");
}
else
return;
}
else if(e.Url.ToString() == sentAddress)
webBrowser1.NavigateTo(fillAddress);
}
I have done tons of assumptions but you will get the general idea: get a list of data, navigate, when the page to fill is loaded fill the row and send the data, when the confirmation is done navigate again to the fill form and repeat until no data is left.
Im trying to implement a search function for when the user enters text in a textbox (tbPartNum) and then clicks the "Find" button it then searches the cells in dataGridView1 and once its found it, it highlights the entire row yellow. My code is as follows which obviously doesn't work it throws an error which states:
"NullReferenceException was unhandled"
and underneath it:
"Object reference not set to an instance of an object."
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
namespace GBstock
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// populate the dataGridView with the Excel File
string connectionString = String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;""", #"C:\Documents and Settings\rghumra\Desktop\Visual Studio\GBstock\GBstock\bin\Debug\FORM TEST.xlsx");
string query = String.Format("select * from [{0}$]", "Sheet1");
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
dataGridView1.DataSource = dataSet.Tables[0];
// populates the comboBox (cbSuppList) with all column headers
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
cbSuppList.Items.Add(col.HeaderText);
}
}
private void btnFind_Click(object sender, EventArgs e)
{
// Code to search the alphanumneric Part Number (in Column1 header called "PART NUMBER") and highlihgt the row
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["PART NUMBER"].Value.ToString().Equals(tbPartNum.Text))
{
dataGridView1.Rows[row.Index].DefaultCellStyle.BackColor = Color.Yellow;
}
}
}
private void fileToolStripMenuItem_Click(object sender, EventArgs e)
{
Instructions instructionForm = new Instructions();
instructionForm.Show();
}
private void partToolStripMenuItem_Click(object sender, EventArgs e)
{
NewPart newPartForm = new NewPart();
newPartForm.Show();
}
private void supplierToolStripMenuItem_Click(object sender, EventArgs e)
{
NewSupplier newSuppForm = new NewSupplier();
newSuppForm.Show();
}
}
}
NullReferenceException you're experiencing most likely comes from the fact that your grid contains null cell values, which get scanned in the foreach of your find handler. Try changing the following line:
if (row.Cells["PART NUMBER"].Value.ToString().Equals(tbPartNum.Text))
To
var cellValue = row.Cells["PART NUMBER"].Value;
if (cellValue != null && cellValue.ToString() == tbPartNum.Text)