Controls only binding to DataReader after a new page refresh - c#

Windows: 7 Home Premium
Visual Studio: 2012
Language: C#
SQL: Server 2008
I am binding some labels and an Image to a DataReader, which is reading from a local DataBase.
The header label, and the Image URL of the image are binding properly, but the rest of the labels only get populated after I refresh the page.
The first image shows the page after I clicked on the user profile link. Notice that the 3 labels in the page have incorrect information:
After a full page refresh, the data is displayed properly:
The code goes as follows
private static string _acceptingChallenges = "0";
private static string _curUser;
private static string _website = "[None]";
private static string _dateJoined = DateTime.Now.ToString();
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.QueryString["user"]))
{
_curUser = (Request.QueryString["user"]);
pnlProfilePublic.Visible = true;
pnlProfilePrivate.Visible = false;
PopulatePublic();
}
else
{
if (!string.IsNullOrEmpty((string) Session["Nickname"]))
{
_curUser = Session["Nickname"].ToString();
pnlProfilePublic.Visible = false;
pnlProfilePrivate.Visible = true;
PopulatePrivate();
}
else
{
Response.Redirect("~/Default.aspx");
}
}
InitiateData();
}
private void InitiateData()
{
if (Master == null) return;
Label lblTitle = (Label)Master.FindControl("lblTitle");
const string strSql = "SELECT * FROM vwGetProfileDetails WHERE memberNickname=#member";
var sqlComm = new SqlCommand(strSql, DataConn.Connect()) { CommandType = CommandType.Text };
sqlComm.Parameters.Add(new SqlParameter("#member", SqlDbType.VarChar, 20)).Value = _curUser;
var rdr = sqlComm.ExecuteReader();
int count = 0;
while (rdr.Read())
{
imgProfile.ImageUrl = rdr["memberAvatarLocation"].ToString();
lblTitle.Text = _curUser + "'s Profile Page";
_acceptingChallenges = rdr["memberAcceptingChallenge"].ToString();
_website = rdr["memberWebsite"].ToString();
_dateJoined = rdr["dateAdded"].ToString();
count = count + 1;
}
rdr.Close();
DataConn.Disconnect();
Response.Write(count);
}

PopulatePublic and PopulatePrivate are called before InitiateData... So they will be stored in the static strings and only populated next time the page is called.
If you are using ASP.Net controls then auto view state will probably be enabled so on postback the controls will be repopulated. So you can do lblWebsite.Text = rdr["memberWebsite"].ToString(); and let ASP.NET manage viewstate.. no need for static strings..

Does _curUser have a value the first time InitiateData is called? I don't think so
Also, you don't want to be using static variables on a web page.

Related

Create buttons dynamically from code behind in ASP.NET

I'm quite new to ASP.NET and I need your help.
I'm programming on an application which should help to fix frequent issues. Users can click the displayed cases if it describes their problem. The application searches for more cases or displays a possible solution.
Now what I need for this is some code which creates the buttons dynamically. I googled some ideas and created some code, however I was not able to get it to work.
It works to create the first selection of buttons with the Default_Load method. Also the OnClick event (ButtonClick_System) works fine which means I get the next selection.
From here it starts messing around. The dynamic buttons created in ButtonClick_System don't have a working OnClick action.
Instead of proceeding with ButtonClick_Question (because of btn_system.Command += ButtonClick_Question; in ButtonClick_System) it seems like it just loads the homepage (maybe something wrong with Page_Load?).
The application should do ButtonClick_Question until no more datasets available in database.
I got the following code:
using System;
using System.Configuration;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Data;
using Oracle.DataAccess.Client;
namespace Application
{
public partial class _default : System.Web.UI.Page
{
// Variables
private string app_name = "Application";
// ----- Page_Load ----- //
protected void Page_Load(object sender, EventArgs e)
{
Default_Load();
Session["Application"] = app_name;
}
// ----- Methods ----- //
// Load homepage
public void Default_Load()
{
pnl_default.Visible = true;
pnl_content.Visible = false;
HtmlGenericControl html_default = new HtmlGenericControl();
html_default.TagName = "div";
string cmdString = "(...)";
DataTable dtSystems = OraQueryData(cmdString);
foreach (DataRow dtRow in dtSystems.Rows)
{
int system_id = Convert.ToInt32(dtRow["SYSTEM_ID"]);
string system_name = Convert.ToString(dtRow["SYSTEM_NAME"]);
var btn_system = new Button
{
ID = "btn_" + system_name,
Text = system_name,
CssClass = "sys_buttons"
};
btn_system.Command += ButtonClick_System;
btn_system.CommandArgument = Convert.ToString(system_id);
html_default.Controls.Add(btn_system);
}
plh_default.Controls.Clear();
plh_default.Controls.Add(html_default);
}
// Button OnClick Events
protected void ButtonClick_System(object sender, CommandEventArgs e)
{
pnl_default.Visible = false;
pnl_content.Visible = true;
HtmlGenericControl html_questions = new HtmlGenericControl();
html_questions.TagName = "div";
int system_id = Convert.ToInt32(e.CommandArgument);
string cmdString = "(...)";
DataTable dtQuestions = OraQueryData(cmdString);
foreach (DataRow dtRow in dtQuestions.Rows)
{
string question_id = Convert.ToString(dtRow["FRAGE_ID"]);
string question_text = Convert.ToString(dtRow["FRAGE_TEXT"]);
var btn_system = new Button
{
ID = "btn_question" + question_id,
Text = question_text,
CssClass = "quest_buttons"
};
btn_system.Command += ButtonClick_Question;
btn_system.CommandArgument = Convert.ToString(system_id);
html_questions.Controls.Add(btn_system);
}
plh_content.Controls.Clear();
plh_content.Controls.Add(html_questions);
}
protected void ButtonClick_Question(object sender, CommandEventArgs e)
{
pnl_default.Visible = false;
pnl_content.Visible = true;
HtmlGenericControl html_ChildQuestions = new HtmlGenericControl();
html_ChildQuestions.TagName = "div";
int parent_id = Convert.ToInt32(e.CommandArgument);
string cmdString = "(...)";
DataTable dtChildQuestions = OraQueryData(cmdString);
foreach (DataRow dtRow in dtChildQuestions.Rows)
{
string question_id = Convert.ToString(dtRow["FRAGE_ID"]);
string question_text = Convert.ToString(dtRow["FRAGE_TEXT"]);
var btn_system = new Button
{
ID = "btn_question" + question_id,
Text = question_text,
CssClass = "quest_buttons"
};
btn_system.Command += ButtonClick_Question;
btn_system.CommandArgument = question_id;
html_ChildQuestions.Controls.Add(btn_system);
}
plh_content.Controls.Clear();
plh_content.Controls.Add(html_ChildQuestions);
}
// ----- Oracle Data Query Methods ----- //
// Create and execute query on database
public static DataTable OraQueryData(string cmdString)
{
string conString = ConfigurationManager.AppSettings["Connection"];
OracleConnection oraCon = new OracleConnection(conString);
OracleCommand oraCmd = new OracleCommand(cmdString, oraCon);
OracleDataAdapter oraDtAd = new OracleDataAdapter(oraCmd.CommandText, oraCon);
DataTable dt = new DataTable();
oraCon.Open();
oraDtAd.Fill(dt);
oraCon.Close();
return dt;
}
}
}
If I've understood the issue correctly I think you're using the wrong controls for the wrong usages.
What I'd suggest you need to do is bind the collection of FAQ records to a repeater or some other data set display control. You can then have an event on the repeater which can handle which record ID has been clicked, post back with that value and refresh the collection of data from that (maybe in another repeater). Don't dynamically create buttons and bind events to them otherwise you will end up in a mess.
Hope this helps.

show Listview column wise and and on button click show same listview in rowwise

I have a task to complete.. i must populate a list view from database and show in column wise and on a button click show it in a row wise... i just completed populating list view from database. now how do i display it it column wise and row wise... please help me...
This is the code i have tried to populate the database...
public partial class DtposMDIParentSystem : Form
{
List<object[]> result = new List<object[]>();
public DtposMDIParentSystem()
{
InitializeComponent();
//create the database connection
OleDbConnection aConnection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\AP_AE\Desktop\DTPOS_APP\DataBase\DtposDatabase.accdb;");
//create the command object and store the sql query
OleDbCommand aCommand = new OleDbCommand("SELECT * FROM Food", aConnection);
try
{
aConnection.Open();
//create the datareader object to connect to table
OleDbDataReader reader = aCommand.ExecuteReader();
int i = 0;
while (reader.Read())
{
result.Add(new Object[reader.FieldCount]);
reader.GetValues(result[i]);
}
reader.Close();
aConnection.Close();
}
catch (InvalidOperationException ex)
{
MessageBox.Show("Invalid Masseage = " + ex.Message);
}
}
private void cmdOlives_Click(object sender, EventArgs e)
{
if (result.Count > 0)
{
string temp = "";
for (int i = 0; i < result[1].Length; i++)
{
temp += result[1][i] + " ";
}
TableOrderListView.Items.Add(temp);
}
}
}
You can achieve something like that by switching between different view modes:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
listView1.View = View.Details;
listView1.HeaderStyle = ColumnHeaderStyle.None;
listView1.Columns[0].Width = listView1.ClientSize.Width - 25;
listView1.Height = 244;
}
else
{
listView1.View = View.List;
listView1.Columns[0].Width = 50;
listView1.Height = 44;
}
}
You need to add one Column for Details view to work!
Note that you will have to adapt the size of the Listview:
In Details mode it will need to be tall enough to show several items
In List mode it will have to to rather wide but must not be tall enough to show more than one item (plus the scrollbar)!
If instead you mean to switch rows and columns you will have to do that in your datasource!

Create a tab for each row found in db

I have a query that selects a table form my db and displays it on some labels, but if the query finds more the one data row it has to display each one of them in a different tab of the form, how can i archive this.
Code:
try
{
mycon.Open();
string querieslabels = "Select *From Alerts where State = #state && Lv =#lv";
oleDbCmd = new OleDbCommand(querieslabels, mycon);
oleDbCmd.Parameters.Add("#state", OleDbType.VarChar, 10).Value = "Open";
oleDbCmd.Parameters.Add("#lv", OleDbType.VarChar, 2).Value = "1";
OleDbDataReader read1;
read1 = oleDbCmd.ExecuteReader();
read1.Read();
state = read1[4].ToString();
if (state != "Closed")
{
lblNum.Text = read1[0].ToString();
lblpress.Text = read1[1].ToString();
txtDescription.Text = read1[2].ToString();
lblDate.Text = read1[3].ToString();
lblOk.Visible = false;
pictureBox2.Visible = false;
mycon.Close();
}
else
{
//Hides labels and other control's
MakeNotVisible();
MessageBox.Show("No alert found");
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
finally
{
mycon.Close();
}
}
What I'm trying to create is some alert system, if there is more than 1 alert it should display in a different tab. Can some one guide me to the solution for this, any help or suggestion is appreciated.
NOTE: I'm using Win Form.
You could create a UserControl, with code that can display one record from a DataTable. Then you can create TabPages and add one new UC to it for each of your rows. Take care not to add too many pages, say no more than 10-15!
Update I just noticed that you are using a DataReader, not a DataTable. No problem, the same solution will worke here, too: Use the added ShowReader method and call it like below..!
Here is an example:
public partial class DataForm : UserControl
{
public DataTable theTable { get; set; }
public DataForm()
{
InitializeComponent();
}
public int showTableRow(int rowIndex)
{
if (theTable == null) return -1;
if (theTable.Rows.Count < rowIndex) return -2;
DataRow row = theTable.Rows[rowIndex];
label1.Text = row[0].ToString();
label2.Text = row[1].ToString();
label3.Text = row[2].ToString();
return 0;
}
public void showReaderRow(OleDbDataReader DR)
{
label1.Text = DR[0].ToString();
label2.Text = DR[1].ToString();
label3.Text = DR[2].ToString();
}
}
For easier access we'll keep a List:
List<DataForm> theDataPages = new List<DataForm>();
Now we can add DataForm pages to the Tab control tabFormPages from the records in a DataTable; here I limit the number to 5:
for (int r = 0; r < DTL.Rows.Count && r < 5; r++)
{
TabPage page = new TabPage( (r+1).ToString("Record #0" ));
DataForm aForm = new DataForm();
aForm.theTable = DTL;
aForm.Parent = page;
aForm.showTableRow(r);
tabFormPages.TabPages.Add(page);
theDataPages.Add(aForm);
}
For use with a DataReader you could write a read loop like this:
while (DR.Read())
{
TabPage page = new TabPage("Alert #"
+ (tabFormPages.TabPages.Count+1).ToString());
DataForm aForm = new DataForm();
aForm.Parent = page;
aForm.showReaderRow(DR);
tabFormPages.TabPages.Add(page);
theDataPages.Add(aForm);
}
First you add the class to your project: Add - Add Usercontrol.
Now you can open it in the Designer and put in all Labels you need as well as the and put a the code. Also flesh out the showRow method to properly display your data in those Labels..
Now you can add such UCs to TabPages in your Tab like I did above.
If you are using a DataTable you can also make one page display a certain record by calling the showRow again:
theDataPages[0].showRow(DTL.Rows.Count - 1);
This will show the last record in the first TabPage.
If you really need to access field on that UC you can create public properties for those fields and access them like so:
public DataTable theTable { get; set; }
public Label Label1 { get; set; }
//..
public DataForm()
{
InitializeComponent();
Label1 = label1;
//..
}
Now you can access the field(s):
if (theDataPages[0].Label1.Text == "Hiho"
theDataPages[0].Label1.BackColor = Color.Green;
Are you using a WinForms application or a WebForms application? You might need an Accordion control (http://www.codeproject.com/Articles/416521/Easy-WinForms-Accordion-Control) or a Tab Control (http://www.c-sharpcorner.com/UploadFile/mahesh/C-Sharp-tabcontrol/) or something similar. You can dynamically create the tabs in them based on the number of rows in your result.

Display data from datagridview vs sql statement, whats proper or more efficient

So I am displaying data from an access DB based on which point image is clicked. I have come up with two different ways to do this and I am curious which would be more efficient.
Here are the two different ways I am currently doing this. If you can recommend a better solution I would love to hear about it.
Solution 1 using datagridview which is binded to the access db.
private void risk1_Click(object sender, EventArgs e)
{
pointid.Text = "7";
int numval = Convert.ToInt32(pointid.Text);
//To get the correct row
int id = numval - 1;
//Point Id of the clicked point
textBox1.Text = id.ToString();
pointlbl.Text = dataGridView1.Rows[id].Cells[2].Value.ToString();
//Cat ID of the clicked point
catId.Text = dataGridView1.Rows[id].Cells[5].Value.ToString();
webBrowser1.DocumentText = dataGridView1.Rows[id].Cells[4].Value.ToString();
webBrowser1.Document.ExecCommand("SelectAll", false, null);
webBrowser1.Document.ExecCommand("Copy", false, null);
using (RichTextBox box = new RichTextBox())
{
box.Paste();
box.Rtf = box.Rtf.Replace("<>", "");
this.htmlRichTextBox1.Rtf = box.Rtf;
}
pointPanel.Visible = true;
homePanel.Visible = false;
}
Solution 2 using a select statement
private void risk2_Click(object sender, EventArgs e)
{
pointid.Text = "2";
int numval = Convert.ToInt32(pointid.Text);
//Setup Connection to access db
string cnString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Adam\\Desktop\\braithwaite.mdb";
//declare Connection, command and other related objects
OleDbConnection conGet = new OleDbConnection(cnString);
OleDbCommand cmdGet = new OleDbCommand();
//try
//{
//open connection
conGet.Open();
//String correctAnswer;
cmdGet.CommandType = CommandType.Text;
cmdGet.Connection = conGet;
cmdGet.CommandText = "SELECT * FROM Points WHERE point_id = "+numval+"";
OleDbDataReader reader = cmdGet.ExecuteReader();
reader.Read();
pointlbl.Text = reader["point"].ToString();
webBrowser1.DocumentText = reader["Description"].ToString();
conGet.Close();
pointPanel.Visible = true;
homePanel.Visible = false;
}

repeater paging viewstate

So finally.. I have my repeater working as I want it to be full of buttons, radio button, image buttons, update panels, AJAX modal popups and a heavy code behind each event.
found out that my repeater getting very slow when the items exceeds 20, so I used paging as a solution. the problem is when I do changes and move on to the next page, all changes are gone when getting back to the previous page. (checked radios, labels, etc all back to normal state).
please help, my system is in production now.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadTasks();
}
void loadTasks()
{
string evalidxxx = Request.QueryString["eval_id"].Trim().Replace(" ", "");
SqlConnection conn = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["GappConnectionString2"].ConnectionString);
try
{
conn.Open();
SqlDataAdapter sqlAdapter = new SqlDataAdapter("SELECT Prog_Task_link.pt_seq, Tasks.task_name, Tasks.task_id FROM Tasks INNER JOIN Prog_Task_link ON Tasks.task_id = Prog_Task_link.task_id INNER JOIN Programs ON Prog_Task_link.prog_id = programs.prog_id INNER JOIN Data_Tracker_prepare ON Programs.prog_id = Data_Tracker_prepare.dtpre_prog_id WHERE Data_Tracker_prepare.eval_id =" + evalidxxx, conn);
System.Data.DataTable dt = new System.Data.DataTable();
sqlAdapter.Fill(dt);
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = dt.DefaultView;
objPds.AllowPaging = true;
objPds.PageSize = 10;
objPds.CurrentPageIndex = CurrentPage;
lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of "
+ objPds.PageCount.ToString();
//Disable Prev or Next buttons if necessary
LinkPrevPage.Enabled = !objPds.IsFirstPage;
LinkNextPage.Enabled = !objPds.IsLastPage;
rptr1.DataSource = objPds;
rptr1.DataBind();
}
catch (SqlException ex)
{
Response.Write(ex.Message);
}
finally { conn.Close(); }
}
public int CurrentPage
{
get
{
// look for current page in ViewState
object o = this.ViewState["_CurrentPage"];
if (o == null)
return 0; // default to showing the first page
else
return (int)o;
}
set
{
this.ViewState["_CurrentPage"] = value;
}
}
protected void LinkPrevPage_Click(object sender, EventArgs e)
{
CurrentPage -= 1;
loadTasks();
}
protected void LinkNextPage_Click(object sender, EventArgs e)
{
CurrentPage += 1;
loadTasks();
}
if you are using .net 4.0 you can use EnablePersistedSelection="True"
sorry to say but this can not be done..
When you are in page one, the rest pages are not actual exists in repeater.
after paging to next page next data will be load so previous data will be reset
i mean to say, When you ask to select all radios, buttons,check boxes are mean what you see. After you change page the other controls are set to default (probably unchecked or reset)
So re design your user interface for what you want to do. And as my suggestion take another button to save the current state of the page.. and then go to next page..
anything other that i can help ??

Categories

Resources