C# to access Database connection troubles - c#

I am new to C#, and 1st post here. I'm am writing a windows form app to be used as a database entry tool. to do this I'm connecting to an access database to read lists and capture new inputs
the error I'm getting is:
System.InvalidOperationException: 'ExecuteReader: Connection property has not been initialized.'
at
OleDbDataReader reader = cmd.ExecuteReader();
The code of the form that is driving the fault is:
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;
using System.Data.OleDb;
namespace Metrics_Data
{
public partial class Login : Form
{
Welcome conndata = new Welcome();
public Login()
{
InitializeComponent();
}
private void btn_exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Login_Load(object sender, EventArgs e)
{
}
private void btn_login_Click(object sender, EventArgs e)
{
//Verify Password and UserID
string Password = null;
OleDbCommand cmd = new OleDbCommand("SELECT * from [Users] WHERE UserID = #UserID",conndata.myconn);
cmd.Parameters.Add("#UserID", OleDbType.VarChar).Value = txt_userid;
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Password = reader["User_Password"].ToString();
}
reader.Close();
cmd.Dispose();
//Load Next Form
UserHome userHomeform = new Metrics_Data.UserHome();
this.Hide();
userHomeform.ShowDialog();
}
}
}
The code that connects from the welcome screen is:
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;
using System.Data.OleDb;
using Microsoft.Win32;
namespace Metrics_Data
{
public partial class Welcome : Form
{
public OleDbConnection myconn = null;
public Welcome()
{
try
{
InitializeComponent();
OleDbConnection myconn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\148.96.211.237\GroupShares\Quality\Electronic Checksheets\MD.accdb;jet OLEDB:Database Password=""Warranty""");
myconn.Open();
lbl_Connstatus.Text = "Connected to DB";
p_dbconn.Visible = true;
}
catch(Exception)
{
MessageBox.Show("error connecting to DB");
btn_cfg.Visible = false;
btn_home.Visible = false;
btn_help.Visible = true;
}
}
class Variables
{
public static dynamic LoginType;
public static dynamic UserID;
public static dynamic Admin;
public static dynamic FirstUse;
public static dynamic Zone;
public static dynamic Shift;
public static dynamic Group;
public static dynamic CDate;
public static dynamic GateLevel;
public static dynamic CountermeasureID;
}
private void Welcome_Load(object sender, EventArgs e)
{
}
private void btn_help_Click(object sender, EventArgs e)
{
//If program is unable to connect with database, initiate sequence where computer's installed access database engine's are displayed in popups, then tell user that program cannot connect
//popups are displayed to help user. If no database engine popups are displayed, see the following URL for troubleshooting information:
//https://support.microsoft.com/en-us/help/2874601/can-t-use-the-access-odbc-driver-or-oledb-provider-outside-office-clic
//A possible fix to this problem is to install access runtime 2013. The URL below has the link to where it's stored locally:
//\\10.35.193.112\Open\AccessRuntime2013
//Update: This also resolves concerns for computers with MS Office 2016, in which the user will receive a popup indicating they have an OLEDB database engine, but the program still will
//not work. IT may be required to give users temporary administrative rights to install AccessRuntime2013.
string AccessDBAsValue = string.Empty;
RegistryKey rkACDBKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Classes");
if (rkACDBKey != null)
{
foreach (string subKeyName in rkACDBKey.GetSubKeyNames())
{
if (subKeyName.Contains("Microsoft.ACE.OLEDB"))
{
MessageBox.Show(Convert.ToString(subKeyName));
}
}
}
MessageBox.Show("The program was unable to connect to the database.");
}
private void btn_exit_Click(object sender, EventArgs e)
{
Environment.Exit(1);
}
private void btn_home_Click(object sender, EventArgs e)
{
Login loginform = new Metrics_Data.Login();
Variables.LoginType = "Data Entry";
loginform.ShowDialog();
}
Any ideas of what I am doing wrong here??? I have verified path to database and the connection string at initial connection does not give any errors, nor do I have any errors in the error space on visual studio.
Many Thanks!

As pointed out in the comments, your constructor is hiding the form property myconn with a local variable, so when you reference the form property, it will be null.
However, I'd be remiss if I did not suggest that you NOT store the connection in a form property. ADO.NET Connections are pooled and are generally cheap to create, so just create one when you need one and dispose of it (using using) when you're done with the query it's created for.
You can store the connection string in one place, but sharing connection objects is generally a bad idea.
Not using a shared connection will also make it simpler since you don't have to worry about checking if the connection is open or not, worrying about opening it twice, etc.

Related

How to enter item from datatable into textbox

First C# form app for me. I can write it in POSH, but I'm trying to graduate and understand C#. I know I have a long way to go, but if someone could help explain this, I would be grateful.
I have a simple SQL table with the following: CLIENT, INPATH, OUTPATH, LIMITERS (PK)
LIMITERS have Unique Values
For each CLIENT, INPATH and OUTPATH are the same.
I am trying to create a form that does the following:
Display a listbox with distinct CLIENT -Working
--- The rest is not working ---
On ListBox Click:
Fill TextBox with INPATH for selected CLIENT
Fill TextBox with OUTPATH for selected CLIENT
Fill ListBox with LIMITERS for selected CLIENT
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;
using Microsoft.Data.SqlClient;
namespace DSI_SFTP_FrontEnd
{
public partial class ClientMain : Form
{
private SqlDbConnect con;
public ClientMain()
{
InitializeComponent();
con = new SqlDbConnect();
con.SqlQuery("Select Distinct CLIENT from Client_Inf");
clientListBoxValues.Items.Clear();
foreach (DataRow dr in con.QueryEx().Rows)
{
clientListBoxValues.Items.Add(dr[0].ToString());
}
}
private void clientListBoxValues_SelectedIndexChanged(object sender, EventArgs e)
{
string text = clientListBoxValues.GetItemText(clientListBoxValues.SelectedItem);
if (text != null)
{
InitializeComponent();
string sql = $"Select INPATH, OUTPATH, LIMITERS from Client_Inf where CLIENT = '{text}'";
con = new SqlDbConnect();
con.SqlQuery(sql);
DataTable dataTable = con.QueryEx();
{
inPathTextBoxValue.Text = dataTable.Rows[0]["INPATH"].ToString();
outPathTextBoxValue.Text = dataTable.Rows[0]["OUTPATH"].ToString();
}
foreach (DataRow dr in dataTable.Rows)
{
limitersListBoxValues.Items.Add(dr[2].ToString());
}
}
}
private void createNewbutton_Click(object sender, EventArgs e)
{
NewClientForm frm = new NewClientForm();
frm.ShowDialog();
}
private void cancelButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
SqlDbConnect.cs
using System.Data;
namespace DSI_SFTP_FrontEnd
{
public class SqlDbConnect
{
private SqlConnection _con;
public SqlCommand _cmd;
private SqlDataAdapter _da;
private DataTable _dt;
public SqlDbConnect()
{
_con=new SqlConnection("Server=<SERVER>;Database=<DB>;Trusted_Connection=True;TrustServerCertificate=True;");
_con.Open();
}
public void SqlQuery(string queryText)
{
_cmd= new SqlCommand(queryText, _con);
}
public DataTable QueryEx()
{
_da = new SqlDataAdapter(_cmd);
_dt= new DataTable();
_da.Fill(_dt);
return _dt;
}
public void NonQueryEx()
{
_cmd.ExecuteNonQuery();
}
}
}
The problem is that you are calling InitializeComponent() in clientListBoxValues_SelectedIndexChanged. InitializeComponent() creates the controls, .i.e., the TextBoxes and ListBoxes, etc. The effect is that you are creating another set of those controls every time the selected index of the ListBox changes.
InitializeComponent() must be called once in the constructor ClientMain() and nowhere else!

How to get Crystal Reports to bind to data provided in a List<T> for some T?

I want to print data from stored procedure in SQL Server with Crystal Report. I used Dapper to connect to SQL Server and fetch the data, but I don't know how to display that data in WPF Viewer and print it as PDF.
Here is the code that I wrote to load data using Dapper:
using System;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Interop;
using MvvmCross.ViewModels;
using Ophtalmology.BusinessLogic.ViewModel.CorrectiveLensesLogic;
using Ophtalmology.View.Reports.PrintingUI;
using Ophtalmology.View.Reports.CorrectiveLensRepports;
using Dapper;
using Microsoft.Data.SqlClient;
using Ophtalmology.BusinessLogic.Helpers;
using Database = Ophtalmology.View.Reports.ConnectionClass.Database;
namespace Ophtalmology.View.CorrectiveLenses
{
/// <summary>
/// Interaction logic for CorrectiveLenses.xaml
/// </summary>
public partial class CorrectiveLenses
{
public CorrectiveLenses()
{
InitializeComponent();
}
private List tblRpt;
private static string ReadCliniqueQuery =>
#"SELECT [Clinique].Id
,Patient.Bar_code
,[Clinique].[FIrst_Name]
,[Clinique].[Last_Name]
,[Age]
,[p1_G]
,[Axe_G]
,[p2_G]
,[VPPPD]
,[VPPPD1_ADITION]
,[p1_D]
,[Axe_D]
,[p2_D]
,[VPPPPG]
,[VPPPG1_ADDITION]
,[DIP]
FROM [dbo].[Clinique],Patient where Patient.Last_Name = Clinique.Last_Name and Patient.First_Name = [Clinique].[FIrst_Name]
Order By [Date_consultation];";
public IEnumerable<Domain.Clinique> GetCliniques()
{
using (IDbConnection context = new SqlConnection(Connection.ConnectionString))
{
return context.Query<Domain.Clinique>(ReadCliniqueQuery).AsList();
}
}
private void PrintButton(object sender, RoutedEventArgs e)
{
Print();
}
private void Print()
{
tblRpt = (List)GetCliniques();
PrintingUI frm = new PrintingUI();
CorrectiveLensfarRepport rpt = new CorrectiveLensfarRepport();
rpt.SetDatabaseLogon("", "", #".\SERVEUR", "Ophtalmology");
rpt.SetDataSource(tblRpt);
frm.ShowDialog();
}
}
}
This is my WPF Viewer
I will be glad for any kid of help ^_^
Thank you

Cannot enter text from class to textbox in form

Cannot enter text from class to textbox in form.
We set a keypress event in the MyTreeView class.
The text box cannot contain characters.
What should I do?
*set of textBox1.
*Change Modifiers for textBox1 properties from private to public
*Change keypress event from private to public
*(It didn't work well, so I keep it private now.)
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;
using System.Diagnostics;
namespace treeview
{
public partial class Form1 : System.Windows.Forms.Form
{
MyTreeView m_tree_view = new MyTreeView();
public Form1()
{
try
{
InitializeComponent();
System.Windows.Forms.TreeNode[] tree1 = new System.Windows.Forms.TreeNode[2];
m_tree_view.Location = new System.Drawing.Point(0, 0);
m_tree_view.Size = ClientSize;
m_tree_view.AllowDrop = true;
tree1[0] = new System.Windows.Forms.TreeNode("TreeNode1");
tree1[1] = new System.Windows.Forms.TreeNode("TreeNode2");
m_tree_view.Nodes.Add("Node1");
Controls.Add(m_tree_view);
}
catch
{
}
}
//This is the code I added.
private void Form1_Load(object sender, EventArgs e)
{
}
}
public class MyTreeView : System.Windows.Forms.TreeView
{
public MyTreeView()
{
try
{
//This is the code I added.
KeyPress += MyTreeView_KeyPress;
}
catch
{
}
}
//This is the code I added.
private void MyTreeView_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
Console.WriteLine("key_press_ok");
//error code↓
//textBox1.Text = "sample";
}
}
}
If you want just to click an button and then print some text i don't understand why you are making another class.
Will be good to make your code efficient and not complicated.
In the main class
private void SendText_Click(object sender, EventArgs e)
{
textBox1.Text = "hi";
}
But if you want to make it complicated and make a class you shuld return i variable and send it to the other class the you can use it.
Learn how to use Public and private first and then use them.
You shuld have a public class which send data and the private to recive and process.
add (Exception ex) to your try catch.
so do:
try
{
// your code
}
catch (Exception ex)
{
MessageBox.Show(ex, "Error in (add where the error is)");
Console.WriteLine(ex);
}
So you will get a detailed Exception Message, maybe it helps you or maybe you will post it here, so we can see what the problem is.
And because you have System.Windows.Forms in your Using Directive
using System.Windows.Forms;
so
System.Windows.Forms.TreeNode[] tree1 = new System.Windows.Forms.TreeNode[2];
is redundant and can be shortened to:
TreeNode[] tree1 = new TreeNode[2];

System.Speech does not recognize speech while debugging

I was going to make a forms application in C# that recognize a voice and then the user could say some simple commands like "hi" and the computer would respond with "hi there, can I help you with someting". I am 100% sure that my mic works but when I debugg the program it seems like it does not recognize any commands or audio from my microphone. I am using Visual Studio Community 2015. I was wondering, is there anything i've missed or done wrong? The computer loads up the form and talks to me but it doesn't recognize my voice. I would appreciate any help. Thanks!
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;
using System.Speech.Synthesis;
using System.Speech.Recognition;
namespace VoiceHost
{
public partial class Form1 : Form
{
SpeechSynthesizer Host = new SpeechSynthesizer();
Choices services = new Choices();
public Form1()
{
SpeechRecognitionEngine UserRecog = new SpeechRecognitionEngine();
services.Add(new string[] {"hi"});
Grammar gr = new Grammar(new GrammarBuilder(services));
Say("hello, my name is voice host, how can I help");
try
{
UserRecog.RequestRecognizerUpdate();
UserRecog.LoadGrammar(gr);
UserRecog.SpeechRecognized += UserRecog_SpeechRecognized;
UserRecog.SetInputToDefaultAudioDevice();
UserRecog.RecognizeAsync(RecognizeMode.Multiple);
}
catch { return; }
}
public void Say(string responseMessage)
{
Host.Speak(responseMessage);
}
private void UserRecog_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
string userOrder = e.Result.Text;
if (userOrder == "hi")
{
Say("hi there, can I help you with someting");
}
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
catch { Exception ex }
that way you'll see if anything breaks in your code.

COMException Problem

Wondering if anyone could help with my problem. Below is the code, and after the code an explination of where the exception is thrown.
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.Web;
using WatiN.Core;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : System.Windows.Forms.Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(createApplications);
Settings.AutoStartDialogWatcher = false;
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
}
private void createApplications()
{
createApp("username", "password", "Test App", "This is just a test description", "http:/mysite.com");
}
private void createApp(String username, String password, String appName, String description, String appUrl) {
var currentBrowser = new IE("http://mysite.com/login/php");
currentBrowser.TextField(Find.ById("username")).TypeText(username);
currentBrowser.TextField(Find.ById("password")).TypeText(password);
currentBrowser.Button(Find.ById("submit")).Click();
currentBrowser.GoTo("http://mysite.com/createmusicapp.php");
currentBrowser.TextField(Find.ById("application_name")).TypeText(appName);
currentBrowser.TextField(Find.ById("application_description")).TypeText(description);
currentBrowser.TextField(Find.ById("application_url")).TypeText(appUrl);
currentBrowser.RadioButton(Find.ById("client_application_desktop_1")).Click();
currentBrowser.RadioButton(Find.ById("client_application_is_writable_1")).Click();
WatiN.Core.Image captchaImage = currentBrowser.Div(Find.ById("recaptcha_image")).Image(Find.ByStyle("display", "block"));
Form2 captcha = new Form2(captchaImage.Src);
captcha.ShowDialog();
}
}
}
The exception is thrown on this line:
currentBrowser.TextField(Find.ById("username")).TypeText(username);
BUT, it's thrown when it gets to this line:
captcha.ShowDialog();
It logs in, and fills in the app details and Form2 loads fine, but once loaded, after around 2-3 seconds the exception happens. I am wondering if it's anything to do with the threads? But I wouldn't know how to solve it if it was.
The complete exception thrown is:
The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED))
Got! Because of your thread, in windows development, microsoft doesn't suggest access UI by thread. If you really need, use mutex to avoid two or more threads accessing the same UI elemnt at the same time.

Categories