C# view data in form linked with foreign key - c#

I have a local database (SQL) with two tables Contact and Address. The Contact table contains 5 address fields (Address1, Address2,...) that are foreign keys linked to the primary key of the Address table. What ik want to do is when I select (for instance using a combobox) a contacts name, view all addresses linked to the contact. I'm a complete noob in C# programming and have no idee to make the above happen. Can anyone show me how I can view the addresses by selecting the contacts name?
EDIT (after trying some coding):
Ok, this is how far I get. I have my two forms. FORM 1 has a datagridview, viewing a button, firstname and lastname. Entering firstname and lastname in textBox1 and textBox2 and pressing button1 results in a list of records that match firstname OR lastname.
Clicking the button in column 0 shows the contactsheet. I've tried to pass firstname and lastname to textboxes tboFNAME and tboLNAME, but nothing appears in these textboxes.
In the next stage I would like to pass the address ID's (foreign keys) to the contactsheet and subsequently load the linked data in the corresponding textboxes.
FORM 1:
public partial class Form1 : Form
{
//SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\xxx\Documents\Visual Studio 2013\Projects\xxx\xxx\xxx.mdf;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\xxx\Documents\Visual Studio 2013\Projects\xxx\xxx\xxx.mdf;Integrated Security=True;Connect Timeout=30");
dataGridView1.Visible = true;
int varCount;
varCount = 0;
int i = 0;
for (i = 1 ; i < dataGridView1.Rows.Count-1; i++)
{
if (!dataGridView1.Rows[i].IsNewRow)
{
if (dataGridView1[3, i].Value.ToString() == textBox1.Text
|| dataGridView1[5, i].Value.ToString() == textBox2.Text
)
{
dataGridView1.Rows[i].Visible = true;
varCount += 1;
Console.WriteLine(varCount);
int RHeight = dataGridView1.RowTemplate.Height;
int gridHeight = (varCount * RHeight) + RHeight;
dataGridView1.Height = gridHeight;
}
else
{
dataGridView1.Rows[i].Visible = false;
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'sAFIREDBDataSet1.contactdata' table. You can move, or remove it, as needed.
this.contactdataTableAdapter1.Fill(this.sAFIREDBDataSet1.contactdata);
this.contactdataTableAdapter.Fill(this.sAFIREDBDataSet.contactdata);
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
String fnameRef = (String)dataGridView1.Rows[e.RowIndex].Cells[3].Value;
String lnameRef = (String)dataGridView1.Rows[e.RowIndex].Cells[5].Value;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
Contactsheet myForm = new Contactsheet();
myForm.getFNAME = fnameRef;
myForm.getLNAME = lnameRef;
myForm.Show();
}
}
}
FORM 2 (Contactsheet)
public partial class Contactsheet : Form
{
public Contactsheet()
{
InitializeComponent();
}
public string getFNAME;
public string getLNAME;
private void Contactsheet_Load(object sender, EventArgs e)
{
tboFNAME.Text = getFNAME;
tboLNAME.Text = getLNAME;
}
}

First of all you must connect to your SQL db as you probably know.
I think that the simplest way will be to use Entity Framework (version 5 or 6).
Create new edmx file, new connection to your database and import your tables.
Try to write some code. May be you figured it out. If not then ask more accurate question with examples of your tries:)

Related

C# DataGridView unable to select cells

I have a DataGridView (DGV) that is NOT using data binding The data is in a SQLite DB
I have written a method that styles the DataGridView
I can populate the DGV with the id of the records in the DB and two string variables
For testing I have 4 TextBox's on the form when I click on the cells I would like to
retrieve the id to transfer that value to another form to use in SQL search
I have tried a number of methods to get data by clicking on the DGV all three are in the
posted code NO I DO NOT WANT to use data binding
SIDE NOTE I have this code working in a VB.Net application no issues
I am new to C# so the code conversion may be the real issue
SO the question is Using C# How to click on a DGV and retrieve the selected value?
public partial class frmSelect : Form
{
string gv_parentInt = "";
string gv_firstName = "";
string gv_lastName = "";
public frmSelect()
{
InitializeComponent();
}
private void frmSelect_Load(object sender, EventArgs e)
{
StyleDGV();
readFriendsData();
}
// Thried these two methods below NO RESULTS
/* private void dgvPerson_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRow row = dgvPerson.Rows[e.RowIndex];
tbID.Text = row.Cells[0].Value.ToString();
tbFName.Text = row.Cells[1].Value.ToString();
tbLName.Text = row.Cells[2].Value.ToString();
}
}*/
/*public void dgvPerson_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (dgvPerson.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
tbMessage.Text = dgvPerson.SelectedCells[0].Value.ToString();
}
}*/
public void dgvPerson_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1 || e.ColumnIndex == -1)
{
tbMessage.Text = "Col " + e.ColumnIndex + " ROW " + e.RowIndex;// for testing
tbMessage.Text = "No Clicking Here";
//return;
}
string strFName;
string strLName;
DataGridViewRow row = dgvPerson.Rows[e.RowIndex];
strFName = dgvPerson.CurrentRow.Cells[0].Value.ToString();
if (strFName != " ")
{
if (strFName == " ")
return;
int intId = System.Convert.ToInt32(row.Cells[0].Value);
gv_parentInt = intId.ToString();
tbID.Text = gv_parentInt;
strFName = row.Cells[1].Value.ToString();
gv_firstName = strFName.Trim();
tbFName.Text = gv_firstName;
strLName = row.Cells[2].Value.ToString();
gv_lastName = strLName.Trim();
tbLName.Text = gv_lastName;
}
tbMessage.Text = "No Data Here";
}
private void readFriendsData()
{
using (SQLiteConnection conn = new SQLiteConnection($"Data Source = '{"Contacts.db"}';Version=3;"))
{
conn.Open();
// The $ sign and '{String or Integer}' how to add variable to SQL Select Statement'gv_parentInt
// Must incorparate BOTH for SELECT to work
// =================================================================================
using (SQLiteCommand cmd = new SQLiteCommand($"SELECT * FROM FriendsData", conn))
{
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
gv_parentInt = rdr["FID"].ToString().Trim();
gv_firstName = rdr["fxFirstName"].ToString().Trim();
gv_lastName = rdr["fxLastName"].ToString().Trim();
dgvPerson.Rows.Add(gv_parentInt, gv_firstName, gv_lastName);
}
rdr.Close();
}
}
conn.Close();
}
//frmPrintLabel.LoadLabel();
}
public void StyleDGV()
{
this.Controls.Add(dgvPerson);
// Set Design of the DataGridView
dgvPerson.DefaultCellStyle.Font = new Font("Bold Tahoma", 11);
dgvPerson.ColumnCount = 3;
dgvPerson.Columns[0].Width = 60;
dgvPerson.Columns[1].Width = 138;
dgvPerson.Columns[2].Width = 138;
// To Set Col Header Size Mode = Enabled
// To Set Col Header Default Cell Styles DO in Properties
dgvPerson.DefaultCellStyle.BackColor = Color.LightBlue;
dgvPerson.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;
dgvPerson.ColumnHeadersHeight = 34;
// DGV Header Names
dgvPerson.Columns[0].Name = " ID";
dgvPerson.Columns[1].Name = "First Name";
dgvPerson.Columns[2].Name = "Last Name";
dgvPerson.Columns[0].HeaderCell.Style.Font = new Font("Bold Tahoma", 11);
dgvPerson.Columns[1].HeaderCell.Style.Font = new Font("Bold Tahoma", 11);
dgvPerson.Columns[2].HeaderCell.Style.Font = new Font("Bold Tahoma", 11);
dgvPerson.Columns[0].HeaderCell.Style.ForeColor = Color.Blue;
dgvPerson.Columns[1].HeaderCell.Style.ForeColor = Color.Blue;
dgvPerson.Columns[2].HeaderCell.Style.ForeColor = Color.Blue;
dgvPerson.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;
dgvPerson.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;
dgvPerson.Columns[2].SortMode = DataGridViewColumnSortMode.NotSortable;
}
private void btnReturn_Click(object sender, EventArgs e)
{
Close();
frmStart fST = new frmStart();
fST.Show();
}
}
}
First let me say that using the TOOL from a VB.Net project was a BIG 4 hour mistake
Here is the code I used to capture the values in the DataGridView
private void dgvPerson_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int ID = 0;// Declare this top level
ID = Convert.ToInt32(dgvPerson.Rows[e.RowIndex].Cells[0].Value.ToString());
tbID.Text = ID.ToString();
tbFName.Text = dgvPerson.Rows[e.RowIndex].Cells[1].Value.ToString();
tbLName.Text = dgvPerson.Rows[e.RowIndex].Cells[2].Value.ToString();
}
Here is what was WRONG Visual Studio 2019 has two DataGridView Tools
One under All Windows Forms and one under Data (see attached screen shot)
I used the one under All Windows Form in the ToolBox hence my code FAILED
Use the DGV under Data in the ToolBox if your are working with C# and SQLite

DataGridView not loading data programmatically

I am working on a Windows application where I get an input from a TextBox and add it to the DataGridView when user clicks on a Button (Add).
My problem is that when I add the text for the first time, it works fine and its added to the grid.
When I add new text, it's not added to the DataGridView. Once the Form is closed and reopened with the same object then I am able to see it.
Code:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (Data == null)
Data = new List<Inputs>();
if (!string.IsNullOrWhiteSpace(txtInput.Text))
{
Data.Insert(Data.Count, new Inputs()
{
Name = txtInput.Text,
Value = string.Empty
});
}
else
{
MessageBox.Show("Please enter parameter value", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
txtInput.Text = "";
gridViewInputs.DataSource = Data;
}
I am not sure what is causing the record not to be added to grid on second add button click.
You could set the DataGridView.DataSource to null before setting a new one.
This would cause the DataGridView to refresh its content with the new data in the source List<Inputs>:
the underlying DataGridViewDataConnection is reset only when the DataSource reference is different from the current or is set to null.
Note that when you reset the DataSource, the RowsRemoved event is raised multiple times (once for each row removed).
I suggest to change the List to a BindingList, because any change to the List will be reflected automatically and because it will allow to remove rows from the DataGridView if/when required: using a List<T> as DataSource will not allow to remove a row.
BindingList<Inputs> InputData = new BindingList<Inputs>();
You can always set the AllowUserToDeleteRows and AllowUserToAddRows properties to false if you don't want your Users to tamper with the grid content.
For example:
public class Inputs
{
public string Name { get; set; }
public string Value { get; set; }
}
internal BindingList<Inputs> InputData = new BindingList<Inputs>();
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = InputData;
}
private void btnAddInput_Click(object sender, EventArgs e)
{
string textValue = txtInput.Text.Trim();
if (!string.IsNullOrEmpty(textValue))
{
InputData.Add(new Inputs() {
Name = textValue,
Value = "[Whatever this is]"
});
txtInput.Text = "";
}
else
{
MessageBox.Show("Not a valid value");
}
}
If you want to keep using a List<T>, add the code required to reset the DataGridView.DataSource:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textValue))
{
//(...)
dataGridView1.DataSource = null;
dataGridView1.DataSource = InputData;
txtInput.Text = "";
}
//(...)

How to use Data Binding Linq to SQL to add custom fields

I am developing a windows forms application. I use DataGridView and data binding with LINQ to SQL. It's working. It binds the whole data.
I need some fields instead of whole table data, for example:
The Customers table contains five fields (name, address, mobile, email, age).
I use the code below to get whole data.
private void AssignLocation_Load(object sender, EventArgs e)
{
// Get Datacontext object to connect with data source
SmartxBillingSystemDataContext dc = new SmartxBillingSystemDataContext();
// create table object
Customer customer = new Customer();
var allcustomers = from c in dc.GetTable<Customer>() select c;
// bind to datagrid
customerBindingSource.DataSource = allcustomers;
// now assign binding source to data grid view
dataGridView1.DataSource = customerBindingSource;
}
Now I just need some fields, e.g. Name and Address.
Additionally, I need to add a button in each row like so:
| A Name | An Address | Button |
| Another Name | Fake Address | Button |
How can I achieve this? Please help.
For click event I use below code
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
popUpLocationWindow();
}
private void popUpLocationWindow()
{
MessageBox.Show("I am clicked");
}
But this code not works.
You can create your own class:
public class MyCustomer
{
public string Name { get; set; }
public string Address { get; set; }
}
and select like this:
var allMycustomers = from c in dc.GetTable<Customer>() select new MyCustomer { Name = c.Name, Address = c.Address };
customerBindingSource.DataSource = allMycustomers;
for button:
DataGridViewButtonColumn btn = new DataGridViewButtonColumn();
btn.HeaderText = "Button";
btn.Text = "Click Me!";
btn.Name = "btn";
dataGridView1.Columns.Add(btn);
btn.UseColumnTextForButtonValue = true;
Update for button click event you can use dataGridView1_CellClick event..
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2)
{
MessageBox.Show((e.RowIndex+1) + " Row " + (e.ColumnIndex+1) + " Column button clicked ");
}
}

Save changes of textbox.text using entity in .net forms

So I'm trying to update a row in a database using the text from a textbox using .net forms.
On pageload I load the value and assign it to the text property of the textbox. Next I allow the user to change the text and click a button to upload, however the value in the database is not changed.
If I change the holter.companyName value to a static string the database updates. Also if I do not assign a companyNameTB.text value at pageloads the update button works as expected.
Any ideas?
protected void Page_Load(object sender, EventArgs e)
{
PortalEntities db = new PortalEntities();
var holterQuery = from holt in db.Holters
where holt.Id == 1
select holt;
Holter holter = holterQuery.Single();
string companyName = holter.CompanyName;
CompanyNameTB.Text = companyName;
}
protected void Button1_Click(object sender, EventArgs e)
{
PortalEntities db = new PortalEntities();
var holterQuery = from holt in db.Holters
where holt.Id == 1
select holt;
Holter holter = holterQuery.Single();
holter.CompanyName = CompanyNameTB.Text;
holter.Id = 1;
db.SaveChanges();
}
It looks like the Page_Load method is overwriting the textbox when the form is submitted. Put it inside of a conditional statement in order to check to see if the request is a post back, like so:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostback)
{
PortalEntities db = new PortalEntities();
var holterQuery = from holt in db.Holters
where holt.Id == 1
select holt;
Holter holter = holterQuery.Single();
string companyName = holter.CompanyName;
CompanyNameTB.Text = companyName;
}
}
This should allow the textbox to be populated from the database when the page is initially loaded, but then when the user submits the form that section of code should be skipped so that the new value in the textbox doesn't get overwritten.
Do this in the Page_Load method, otherwise the value in the textBox is refreshed to the original one at any page request (so the post back request too)
if(!Page.IsPostBack)
{
PortalEntities db = new PortalEntities();
var holterQuery = from holt in db.Holters
where holt.Id == 1
select holt;
Holter holter = holterQuery.Single();
string companyName = holter.CompanyName;
CompanyNameTB.Text = companyName;
}
And you don't need this line is the Button1_Click method
holter.Id = 1;

Why does the datagridview update, but the db does not?

I have been searching this answer for three days and so far no answer I found has worked. I am using a SQL db with a DataSet, Binding Source, Table Adapter, Table Adapter Manager, Binding Navigator and DataGridView. I am trying to use the fields on the left to update the db and just use the DataGridView as a view. The app updates from the textboxes to the DataGridView just fine but when I use the Update button to call:
this.Validate();
this.directoryBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.companyContactsDataSet1);
Nothing happens and the db stays the same. I do not know how to watch the variables in the Dataset, to see what their values are, so I have no clue if the DataSet is passing values into the UpdateAll function.
Here is the main code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'companyContactsDataSet1.Directory' table. You can move, or remove it, as needed.
this.directoryTableAdapter.Fill(this.companyContactsDataSet1.Directory);
lblTotalRows.Text = "Total number of records: " +directoryBindingSource.Count.ToString();
position = directoryBindingSource.Position + 1;
lblCurrentRow.Text = "Current Row: " + position.ToString();
}
private void bindingNavigator1_RefreshItems(object sender, EventArgs e)
{
//lblCurrentRowCopy.Text = "Current Row: "; //+ this.bindingNavigator1.CountItemFormat.ToString();
}
int position = 0;
private void btnPrevious_Click(object sender, EventArgs e)
{
directoryBindingSource.MovePrevious();
position = directoryBindingSource.Position + 1;
lblCurrentRow.Text = "Current Row: " + position.ToString();
}
private void btnNext_Click(object sender, EventArgs e)
{
directoryBindingSource.MoveNext();
position = directoryBindingSource.Position + 1;
lblCurrentRow.Text = "Current Row: " + position.ToString();
}
int count = 0;
private void btnAddRecord_Click(object sender, EventArgs e)
{
//This event handler moves to the last record and gets the value of the ID column.
//Then it parces that string value in the count variable. The position of the records
//is recorded and sent to the position label and a new row is added for the next record.
//The add.New function clears the fields and begins a new row. Then the count variable
//is incremented by one and cast to string to be placed into the idTextBox field.
//This was my solution to not having a way to use an autonumber field for ID. When I
//tried to use the SQL newID function in a table it was not allowed. I had many problems trying to use this line
//[Id] uniqueidentifier ROWGUIDCOL DEFAULT NEWID() not null IDENTITY ,
directoryBindingSource.MoveLast();
count = Int32.Parse(this.dataGridView1.CurrentCell.Value.ToString());
directoryBindingSource.AddNew(); // This throws an exception if the cursor is in any column but the ID column when caoo
count++;
idTextBox.Text = count.ToString();
position = directoryBindingSource.Position + 1;
lblCurrentRow.Text = "Current Row: " + position.ToString();
lblTotalRows.Text = "Total number of records: " + directoryBindingSource.Count.ToString();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
//need to call binding source update method
try
{
//this.directoryTableAdapter.Insert(count, fNameTextBox.Text, lNameTextBox.Text, addressTextBox.Text, cityTextBox.Text,
//stateTextBox.Text, zipTextBox.Text, emailTextBox.Text, phoneTextBox.Text, deptTextBox.Text);
this.Validate();
this.directoryBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.companyContactsDataSet1);
//this.companyContactsDataSet1.AcceptChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
That's all I can think of for now.

Categories