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
Related
I have spent some time designing my first project using C#, it is a Windows form project with 8 buttons on the side. pressing one of the buttons will open another form within the parent form as a window. On clicking the button the new form loads up about 27 objects mostly Labels, Textboxes, Comboboxes and a few DateTimePickers. For some reason it you can see it drawing the boxes and it looks slow. I have an SQL db included with my project which is tiny and contains only 2 rows of data. It is very dishearting to spend all that time working on it only to see it run like a ZX Spectrum. I am using Microsoft Visual Studio 2019 and is fully updated. I have no errors, no warnings thank god but the performance is horrible. One of the comboBoxes when selected will make visible 3 more textBoxes and even making those visible is really slow. Is there something I am doing wrong or is there a way to have it working faster please?
This is the code of my childForm which opens from the main parentForm, sorry is is a bit long but it is all of it.
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace AvianManager.Forms
{
public partial class formMyBirds : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Dion\Documents\AvianManager.mdf;Integrated Security=True;Connect Timeout=30");
public formMyBirds()
{
InitializeComponent();
}
private void formMyBirds_Load(object sender, EventArgs e)
{
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
var form = Application.OpenForms["formMyBirdsHelper"]; // Lookup form and check if already open
if (form == null)
{
formMyBirdsHelper MyBirdsHelper = new formMyBirdsHelper(); // Instantiate a FormMyBirdsHelp object.
MyBirdsHelper.Show(); // Show FormMyBirdsHelp and
}
}
private void comboBoxLegBandType_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = this.comboBoxLegBandType.GetItemText(this.comboBoxLegBandType.SelectedItem);
if (selected != "None" || selected == null)
{
textBoxLegBandID.Visible = true;
labelLegBandId.Visible = true;
textBoxLegBandSize.Visible = true;
labelLegBandSize.Visible = true;
}
else
{
textBoxLegBandID.Visible = false;
labelLegBandId.Visible = false;
textBoxLegBandSize.Visible = false;
labelLegBandSize.Visible = false;
}
}
private void comboBoxPrevOwner_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = this.comboBoxPrevOwner.GetItemText(this.comboBoxPrevOwner.SelectedItem);
if (selected != "No")
{
textBoxLastOwnerName.Visible = true;
labelLastOwnerName.Visible = true;
textBoxLastOwnerFone.Visible = true;
labelLastOwnerFone.Visible = true;
textBoxLastOwnerAddr.Visible = true;
labelLastOwnerAddr.Visible = true;
}
else
{
textBoxLastOwnerName.Visible = false;
labelLastOwnerName.Visible = false;
textBoxLastOwnerFone.Visible = false;
labelLastOwnerFone.Visible = false;
textBoxLastOwnerAddr.Visible = false;
labelLastOwnerAddr.Visible = false;
}
}
private void comboBoxVitalStatus_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = this.comboBoxVitalStatus.GetItemText(this.comboBoxVitalStatus.SelectedItem);
if (selected != "Alive")
{
dateTimeDateOfDeath.Visible = true;
labelDateOfDeath.Visible = true;
textBoxCauseOfDeath.Visible = true;
labelCauseOfDeath.Visible = true;
}
else
{
dateTimeDateOfDeath.Visible = false;
labelDateOfDeath.Visible = false;
textBoxCauseOfDeath.Visible = false;
labelCauseOfDeath.Visible = false;
}
}
private void comboBoxRetained_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = this.comboBoxRetained.GetItemText(this.comboBoxRetained.SelectedItem);
if (selected != "Yes")
{
dateTimeRelinquishedDate.Visible = true;
labelRelinquishedDate.Visible = true;
}
else
{
dateTimeRelinquishedDate.Visible = false;
labelRelinquishedDate.Visible = false;
}
}
private void textBoxUid_TextChanged(object sender, EventArgs e)
{
SqlCommand cmd1 = new SqlCommand("select top 1 * from dbMyBirds where db_Uid = '" + textBoxUid.Text + "'", connection);
cmd1.Parameters.AddWithValue("db_Uid", textBoxUid.Text);
SqlDataReader reader1;
connection.Open();
reader1 = cmd1.ExecuteReader();
if (reader1.Read())
{
labelResult.Text = "Found";
textBoxName.Text = reader1["db_Name"].ToString();
textBoxSpecies.Text = reader1["db_Species"].ToString();
comboBoxLegBandType.Text = reader1["db_LegBandType"].ToString();
textBoxLegBandID.Text = reader1["db_LegBandId"].ToString();
textBoxLegBandSize.Text = reader1["db_LegBandSize"].ToString();
comboBoxPrevOwner.Text = reader1["db_PrevOwner"].ToString();
textBoxLastOwnerName.Text = reader1["db_PrevOwnerName"].ToString();
textBoxLastOwnerFone.Text = reader1["db_PrevOwnerFone"].ToString();
textBoxLastOwnerAddr.Text = reader1["db_PrevOwnerAddr"].ToString();
comboBoxIsHybrid.Text = reader1["db_Hybrid"].ToString();
comboBoxRearedBy.Text = reader1["db_RearedBy"].ToString();
textBoxDisformaties.Text = reader1["db_Disformaties"].ToString();
comboBoxVitalStatus.Text = reader1["db_VitalStatus"].ToString();
dateTimeDateOfDeath.Text = reader1["db_DateDied"].ToString();
textBoxCauseOfDeath.Text = reader1["db_CauseOfDeath"].ToString();
comboBoxRetained.Text = reader1["db_Retained"].ToString();
dateTimeRelinquishedDate.Text = reader1["db_RelinquishedDate"].ToString();
dateTimeHatchDate.Text = reader1["db_HatchDate"].ToString();
dateTimeFledgeDate.Text = reader1["db_FledgeDate"].ToString();
comboBoxMaleParentHybrid.Text = reader1["db_MPisHybrid"].ToString();
textBoxMaleParentId.Text = reader1["db_MPUid"].ToString();
textBoxMaleParentSpecies.Text = reader1["db_MPSpecies"].ToString();
comboBoxHenParentHybrid.Text = reader1["db_FPisHybrid"].ToString();
textBoxHenParentId.Text = reader1["db_FPUid"].ToString();
textBoxHenParentSpecies.Text = reader1["db_FPSpecies"].ToString();
textBoxNotes.Text = reader1["db_Notes"].ToString();
}
else
{
resetInputs();
if (textBoxUid.Text == "")
{
labelResult.Text = "Live Search";
}
else
{
labelResult.Text = "Nothing Found";
}
}
connection.Close();
}
//Reset input fields if no results
private void resetInputs()
{
string dt2;
DateTime date2 = DateTime.Now;
dt2 = date2.ToShortDateString(); // display format: 15/07/2021
textBoxName.Text = "";
textBoxSpecies.Text = "";
comboBoxLegBandType.Text = "Select";
textBoxLegBandID.Text = "";
textBoxLegBandSize.Text = "";
comboBoxPrevOwner.Text = "Select";
textBoxLastOwnerName.Text = "";
textBoxLastOwnerFone.Text = "";
textBoxLastOwnerAddr.Text = "";
comboBoxIsHybrid.Text = "Select";
comboBoxRearedBy.Text = "Select";
textBoxDisformaties.Text = "";
comboBoxVitalStatus.Text = "Select";
dateTimeDateOfDeath.Text = dt2;
textBoxCauseOfDeath.Text = "";
comboBoxRetained.Text = "Select";
dateTimeRelinquishedDate.Text = dt2;
dateTimeHatchDate.Text = dt2;
dateTimeFledgeDate.Text = dt2;
comboBoxMaleParentHybrid.Text = "Select";
textBoxMaleParentId.Text = "";
textBoxMaleParentSpecies.Text = "";
comboBoxHenParentHybrid.Text = "Select";
textBoxHenParentId.Text = "";
textBoxHenParentSpecies.Text = "";
textBoxNotes.Text = "";
}
private void buttonInsert_Click(object sender, EventArgs e)
{
}
}
}
I'm setting datagridview as object and show in windows form in Textbox change event. When open form and start texting into textbox then datagridview is show but when text is empty or null datagridview continue been visible. How can I accomplish datagridview invisible in windows form?
This is for C#. I have tried to dispose datagridview in if clause but it didn't work.
Here is my code:
public class CreateDataGridView
{
public DataGridView clientsDgv = new DataGridView();
public CreateDataGridView()
{
clientsDgv.ReadOnly = true;
clientsDgv.Name = "clientsDgv";
clientsDgv.AllowUserToAddRows = false;
clientsDgv.AllowUserToDeleteRows = false;
clientsDgv.AllowUserToResizeRows = false;
}
public DataGridView Createdgv()
{
return clientsDgv;
}
Here is my code in windows form.
//Get datagridview in windows form textbox change event
private void TxtID_TextChanged(object sender, EventArgs e)
{
switch (this.cmbSelectAction.SelectedIndex)
{
case 1:
CreateDataGridView clientsdgv = new CreateDataGridView();
//clientsdgv.clientsDgv
Controls.Add(clientsdgv.clientsDgv);
clientsdgv.clientsDgv.BringToFront();
DesignDataGridView designdgv = new DesignDataGridView();
designdgv.ClientsDataGridFormatting(clientsdgv.clientsDgv);
designdgv.ClientsDataGridPosition(clientsdgv.clientsDgv, txtID);
//SetDoubleBuffered.SetDoubleBuffering(clientsdgv.clientsDgv, true);
if (string.IsNullOrEmpty(txtID.Text) || txtID.Text == "0")
{
clientsdgv.clientsDgv.DataSource = null;
clientsdgv.clientsDgv.Update();
clientsdgv.clientsDgv.Dispose();
clientsdgv.clientsDgv.Visible = false;
return;
}
else
{
GetSqlData getSqlData = new GetSqlData();
try
{
clientsdgv.clientsDgv.SuspendLayout();
columnName = "PersonalIDBulstat";
ID = txtID.Text;
clientsdgv.clientsDgv.Visible = true;
clientsdgv.clientsDgv.DataSource = getSqlData.SearchClientsInSql(columnName, ID);
clientsdgv.clientsDgv.Update();
clientsdgv.clientsDgv.ResumeLayout();
}
catch
{
title = "Clients";
SetMessageBoxTypes.MessageBoxContactAdminOk(title);
}
}
break;
}
}
Thank you in advance!
It is my working code when form is load where dgvClients is declare as DataGridView:
private void Clients_Load(object sender, EventArgs e)
{
CreateDataGridView clientsdgv = new CreateDataGridView();
dgvClients = clientsdgv.dgvClients;
}
private void TxtID_TextChanged(object sender, EventArgs e)
{
switch (this.cmbSelectAction.SelectedIndex)
{
case 1:
Controls.Add(dgvClients);
dgvClients.BringToFront();
DesignDataGridView designdgv = new DesignDataGridView();
designdgv.ClientsDataGridPosition(dgvClients, this.txtID);
GetSqlData getSqlData = new GetSqlData();
if (string.IsNullOrEmpty(txtID.Text) || txtID.Text == "0")
{
dgvClients.DataSource = null;
dgvClients.Update();
dgvClients.Visible = false;
return;
}
else
{
try
{
dgvClients.SuspendLayout();
columnName = "PersonalIDBulstat";
ID = txtID.Text;
dgvClients.Visible = true;
dgvClients.DataSource = getSqlData.SearchClientsInSql(columnName, ID);
dgvClients.Update();
dgvClients.ResumeLayout();
}
catch
{
title = "Clients";
SetMessageBoxTypes.MessageBoxContactAdminOk(title);
}
}
break;
}
}
I'm setting a IT project for the school and i got a problem with the datagridview in c# Winform.
I made a first form with a datagridview connected to my db and i want to make a button who can delete a row from the datagridview if needed.
To make sure the client doesn't make a mistake, i create another form where it ask "do you want to delete this row ? (yes/no)", that's a basic form (label + button).
But when i want to close this form, i go to a function in my first datagrid who will initialize this grid from the start of the program and in this code I use Datagridview.DataSource to make a loop.
The problem is marked here, and when I print my DataSource, it print me nothing like there is no DataSource...
Does anyone the reason or how to keep the DataSource from the previous form when you pop's up a new one ?
My code for the initial grid
public void InitDatagrid()
{
//Initialize the tools
CancelMod.Visible = false;
ApplyMod.Visible = false;
Modifie.Visible = true;
Prevbtn.Visible = true;
ClientCommand.Enabled = true;
Client_Pieces.Enabled = true;
Prices.Enabled = true;
PieceCommand.Enabled = true;
Pieces.Enabled = true;
textBox1.Enabled = true;
RowAdd.Visible = false;
RowDelete.Visible = false;
textboxDel.Visible = false;
labelDel.Visible = false;
dataGridView1.EditMode =
DataGridViewEditMode.EditProgrammatically;
textBox1.Text = "";
this.pieceTableAdapter.Fill(this.mykitboxDataSet5.piece);
//Put the color of the columns as white (initial color)
for (var i = 0; i < ((DataTable)dataGridView1.DataSource).Columns.Count; i++)
{
dataGridView1.Columns[i].DefaultCellStyle.BackColor = Color.White;
}
int count = ((DataTable)dataGridView1.DataSource).Columns.Count;
//Put the changed cells color as white (initial color)
if (count == 8)
{
dataGridView2.EditMode =
DataGridViewEditMode.EditProgrammatically;
DeleteCommand.Visible = false;
textBoxDel2.Visible = false;
labelDel2.Visible = false;
for (int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count.ToString()); i++)
{
//Column = payment_status and command_status
dataGridView1.Rows[i].Cells[6].Style.BackColor = Color.White;
dataGridView1.Rows[i].Cells[7].Style.BackColor = Color.White;
}
}
}
Here is my code for the pop up
public PopUpDel(string codedb, string text, DataGridView ds)
{
this.codedb = codedb;
InitializeComponent();
code.Text = codedb;
label1.Text = text;
Console.WriteLine(ds);
}
private void yes_Click(object sender, EventArgs e)
{
SKGridPage sk = new SKGridPage();
sk.SqlConnection();
MySqlCommand command = conn.CreateCommand();
command.CommandText = string.Format("DELETE FROM piece WHERE code = '{0}'", this.codedb);
Console.WriteLine(command.CommandText);
try
{
conn.Open();
command.ExecuteNonQuery();
}
catch (Exception x)
{
Console.WriteLine(x.Message);
}
conn.Close();
this.Close();
sk.InitDatagrid();
}
private void no_Click(object sender, EventArgs e)
{
this.Close();
}
}
How can i get the value of outlet ID it on a comboBox?
here is my code to getting the values from Database and store it on a combobox.
public partial class Addstock : Form
{
String connectionString = ConfigurationManager.ConnectionStrings["TCConnectionString"].ConnectionString;
List<BOStockTransfer> StockList = new List<BOStockTransfer>();
int updateIndex = -1;
public Addstock()
{
InitializeComponent();
}
private void Addstock_Load(object sender, EventArgs e)
{
loadstock();
GetOutlets();
Getproduct();
GetGetWH();
cmdoutletID.Visible = false;
lbloutid.Visible = false;
cmdwh.Visible = false;
lblwh.Visible = false;
}
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletId";
}
}
Thank you for your help!
you are setting :
cmdoutletID.Visible = false;
what makes the combobox invisible
you have to set it as follows :
cmdoutletID.Visible = true;
After you added the images , the column name is outletID and Not outletId
so change your code as follows :
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletID";
cmdoutletID.ValueMember = "outletID";
cmdoutletID.Enabled = true;
}
}
The combo box has two properties which determine where it loads data from:
DisplayMember
ValueMember
The "ValueMember" property defines which named field populates the ListItem's "ValueProperty". That way, when you do combobox.SelectedItem.Value, you will get the value stored in the named field you specified for "ValueProperty".
Assuming that you are certain that your query is returning rows, perhaps try adding the items "manually" rather than relying on automatic databinding.
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
cmdoutletID.DisplayMember = "outletId";
cmdoutletID.ValueMember = "pkID";
cmdoutletID.BeginUpdate();
try
{
cmdoutletID.Items.Clear();
foreach (var row in ds_OutletList.Tables[0].Rows)
cmdoutletID.Items(new { outletid = row["outletid"], pkID = row["primaryKeyIDFieldName"] });
}
finally { cmdoutletID.EndUpdate(); }
}
Try this:
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletname";
cmdoutletID.ValueMember = "outletId";
}
To capture selected value, for example on button click:
protected button1_Click(object o, EventArgs e)
{
var selectedId = cmboutletID.SelectedValue;
MessageBox.Show(selectedId);
}
Using VS 2010, C#, .NET 3.5
I have three User Defined Web Controls:
Control 1 has a ListBox and A Button
Control 2 has three Text-Boxes two DropDownLists and three Buttons
Control 3 has only a Table which is populated in code.
I have two pages:
Page 1 has Control 2 and Control 3
Page 2 has Control 1, Control 2, and Control 3
Functionality of Control 2 works perfectly on Page 1.
However, on Page 2 when the submit button is clicked, both DropDownLists ALWAYS show SelectedIndex = 0 and SelectedValue = "0".
All three Text Boxes and Buttons retain their value on both pages when the Submit Button on Control 2 is clicked. Only the DropDownLists fail to retain their value.
For reference, here is the code in the Submit Button OnClick event:
protected void btnSubmit_Click(object sender, EventArgs e)
{
clsLog.WriteLog("TrainingForm.ascx - Submit.");
tcCategoryError.Text = " ";
tcDateError.Text = " ";
tcDescriptionError.Text = " ";
tcHoursError.Text = " ";
tcMethodError.Text = " ";
foreach (Control c in this.Controls)
{
LogControls(c);
}
c_iTID = Convert.ToInt32(hTID.Value);
c_szUserName = hUserName.Value;
bool bValid = true;
DateTime dtTrainingDate = DateTime.MinValue;
string szTrainingDescription = "";
decimal dHours = 0M;
int iCategoryID = 0;
int iMethodID = 0;
if (!DateTime.TryParse(txtTrainingDate.Text, out dtTrainingDate))
{
bValid = false;
tcDateError.Text = "Please Enter Valid Training Date";
}
if (!decimal.TryParse(txtTrainingHours.Text, out dHours))
{
bValid = false;
tcHoursError.Text = "Please Enter Valid Training Hours";
}
if (this.ddlCategory.SelectedValue == "0")
{
bValid = false;
tcCategoryError.Text = "Please Select Training Category";
}
else
iCategoryID = Convert.ToInt32(this.ddlCategory.SelectedValue);
if (this.ddlTrainingMethod.SelectedValue == "0")
{
bValid = false;
tcMethodError.Text = "Please Select Training Method";
}
else
iMethodID = Convert.ToInt32(this.ddlTrainingMethod.SelectedValue);
if (txtTrainingDescription.Text.Trim() == "")
{
bValid = false;
tcDescriptionError.Text = "Please Enter Training description.";
}
else
szTrainingDescription = txtTrainingDescription.Text.Trim();
if (bValid)
{
clsData.UpdateTraining(c_iTID, "", c_szUserName, dtTrainingDate, szTrainingDescription, iCategoryID, dHours, iMethodID);
TrainingID = 0;
ClearForm();
}
OnEvent(new MyEventArgs(c_szUserName));
}
Code to populate DropDowns (part of the User Defined Control)
protected void BindddlCategory(int iCategoryID)
{
DataTable dt = clsData.GetTrainingCategories();
ddlCategory.Items.Clear();
ddlCategory.AppendDataBoundItems = true;
ddlCategory.Items.Add(new ListItem("Select Training Category", "0"));
ddlCategory.DataSource = dt;
ddlCategory.DataTextField = "TrainingCategory";
ddlCategory.DataValueField = "CID";
ddlCategory.DataBind();
if (iCategoryID != 0)
ddlCategory.SelectedValue = iCategoryID.ToString();
}
protected void BindddlCategory()
{
BindddlCategory(0);
}
protected void BindddlTrainingMethod(int iMethodID)
{
DataTable dt = clsData.GetTrainingMethods();
ddlTrainingMethod.Items.Clear();
ddlTrainingMethod.AppendDataBoundItems = true;
ddlTrainingMethod.Items.Add(new ListItem("Select Training Method", "0"));
ddlTrainingMethod.DataSource = dt;
ddlTrainingMethod.DataTextField = "TrainingCategory";
ddlTrainingMethod.DataValueField = "CID";
ddlTrainingMethod.DataBind();
if (iMethodID != 0)
ddlTrainingMethod.SelectedValue = iMethodID.ToString();
}
protected void BindddlTrainingMethod()
{
BindddlTrainingMethod(0);
}
FYI, the DDLs are NOT populated at Page load but implicitly populated when the event to show the form of the control is fired:
public void ShowTrainingEntry(int iTrainingID)
{
clsLog.WriteLog("TrainingForm.ascx - ShowTrainingEntry(" + iTrainingID.ToString() + ")");
hTID.Value = iTrainingID.ToString();
hUserName.Value = UserName;
int iCategoryID = 0;
int iMethodID = 0;
if (iTrainingID != 0)
{
DataTable dt = clsData.GetTrainingRecord(iTrainingID);
if (dt.Rows.Count == 1)
{
txtTrainingDate.Text = Convert.ToDateTime(dt.Rows[0]["TrainingDate"]).ToString("MM/dd/yyyy");
txtTrainingHours.Text = Convert.ToDecimal(dt.Rows[0]["Hours"]).ToString("N1");
txtTrainingDescription.Text = dt.Rows[0]["TrainingDescription"].ToString();
int.TryParse(dt.Rows[0]["CategoryCID"].ToString(), out iCategoryID);
int.TryParse(dt.Rows[0]["MethodCID"].ToString(), out iMethodID);
}
ShowChangeMessage(iCategoryID == 0 | iMethodID == 0);
ShowDeleteButton(true);
ShowCancelButton(true);
}
BindddlCategory(iCategoryID);
BindddlTrainingMethod(iMethodID);
tblMain.Visible = true;
}
Anyone have any ideas on why this is happening?
Thanks,
John
If you are adding the UserControls dynamically, you need to make sure they are added no later than Page_Init. This is so the controls are present when the page attempts to set the values from the PostBack.