Create dynamic buttons while reading from SQL Server - c#

I'm using this code while reading from SQL Server. The problem is that it runs the loop as many times are my SQL Server results.
SqlCommand sqlCmd = new SqlCommand("Select Name from TablesDesigner", con);
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
while (sqlReader.Read())
{
for (int row = 0; row < NUM_ROWS; row++)
{
TableRow tablerow = new TableRow(this);
TableLayout.LayoutParams linearLayoutParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MatchParent, TableLayout.LayoutParams.MatchParent, 1.0f);
tablerow.LayoutParameters = linearLayoutParams;
table.AddView(tablerow);
for (int col = 0; col < NUM_COLS; col++)
{
int FINAL_COL = col;
int FINAL_ROW = row;
Button btn = new Button(this);
TableRow.LayoutParams linearLayoutParams2 = new TableRow.LayoutParams(TableRow.LayoutParams.MatchParent, TableRow.LayoutParams.MatchParent, 1.0f);
btn.LayoutParameters = linearLayoutParams2;
btn.Text = sqlReader["Name"].ToString();
tablerow.AddView(btn);
}
}
}
My result is below:
And my desired result is:
Where should I place my loop for getting the desired result? Or should I break it somehow?
Thanks.
Also what if I want to use two rows??

When confronted with a difficult problem, break it down into manageable bits (this is good coding practice anyway).
First, get the data you need into a single list. Don't forget to Dispose your DataReader.
public List<string> GetButtonNames()
{
var buttonNames = new List<string>();
SqlCommand sqlCmd = new SqlCommand("Select Name from TablesDesigner", con);
using (var sqlReader = sqlCmd.ExecuteReader())
{
while (sqlReader.Read())
{
buttonNames.Add(sqlReader["Name"].ToString());
}
}
return buttonNames;
}
Then write a function to organize it into a 2D list. I stole the logic for this from this question.
public static List<List<string>> Make2DList(List<string> input, int width=4)
{
var output = new List<List<string>>();
for (int i=0; i < input.Count; i+= width)
{
output.Add(input.GetRange(i, Math.Min(width, input.Count - i)));
}
return output;
}
Now you have a list of lists. The "outer" list corresponds to each table row. The inner list is a list of column values within that row.
Now all you need is code to make it into a table. Because we organized the data into a grid already, we can use normal foreach syntax which makes it very easy.
public void RenderButtonTable(List<List<string>> names)
{
var layout = new TableLayout.LayoutParams
(
TableLayout.LayoutParams.MatchParent,
TableLayout.LayoutParams.MatchParent,
1.0f
);
tablerow.LayoutParameters = layout;
foreach (var row in names)
{
TableRow tablerow = new TableRow(this);
tablerow.LayoutParameters = layout;
table.AddView(tablerow);
foreach (var col in row)
{
Button btn = new Button(this);
btn.Text = col;
tablerow.AddView(btn);
}
}
}
Put it all together:
void CreateDynamicButtonsWhileReadingFromSQLServer()
{
var buttonNames = GetButtonNames();
var gridData = Make2DList(buttonNames, NUM_COLS);
RenderButtonTable(gridData);
}

Related

How to fetch values from database in pivot while working with dynamic controls in asp.net c#

I'm Prateek, trying to create an application that takes user inputs from the controls that are being generated dynamically such as a TextBox or a DropDownList.
These controls are generated from the database values itself i.e., I'm storing all the values that are to be created in a table named 'usertasks'.
Now, everything is working fine and controls are dynamically generated, the user inputs are stored in another table named 'taskEntries'. The problem I'm facing is with the values being fetched:
The above image is of a table to save what kind of controls the user wants to create and their labels.
Another image to show how data is being stored right now:
How I want the data to be fetched:
Kindly let me know how do I do it in asp.net c#.
What I tried?
//Below code to get all data into a DataTable
protected void getData()
{
using (SqlConnection con = new SqlConnection(ConnectionManager.ConString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("select (cdate + ', ' + ctime) as 'Date', taskID as 'Task ID', deptID as 'Department ID', empID as 'Employee ID', question as 'Question', userInput as 'Input' from taskEntries", con))
{
DataTable dt = new DataTable();
sda.Fill(dt);
ViewState["dt"] = dt;
BindGrid(dt, false);
}
con.Close();
}
ConvertRowsToColumns();
}
//Below code to bind the gridview
private void BindGrid(DataTable dt, bool rotate)
{
grdUserData.ShowHeader = !rotate;
grdUserData.DataSource = dt;
grdUserData.DataBind();
if (rotate)
{
foreach (GridViewRow row in grdUserData.Rows)
{
row.Cells[0].CssClass = "header";
}
}
}
//Below code to convert the rows to columns
private void ConvertRowsToColumns()
{
DataTable dt = (DataTable)ViewState["dt"];
DataTable dt2 = new DataTable();
for (int i = 0; i <= dt.Rows.Count; i++)
{
String Question = Convert.ToString(dt.Rows[i]["question"]);
String InputType = Convert.ToString(dt.Rows[i]["inputType"]);
dt2.Columns.Add(Question);
dt2.Columns.Add(InputType);
}
for (int i = 0; i < dt.Columns.Count; i++)
{
dt2.Rows.Add();
dt2.Rows[i][0] = dt.Columns[i].ColumnName;
}
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
dt2.Rows[i][j + 1] = dt.Rows[j][i];
}
}
BindGrid(dt2, true);
}

novacode docx , create word table from datatable

I'm trying to loop over the datatable and create word table. So far if I have 3 rows in the datatable they are being inserted into the first row of my Microsoft Word table, instead I want every row from the datatable into a new row in Microsoft Word table.
Below is my code :
protected void Button2_Click(object sender, EventArgs e)
{
PullData();
gvd2.DataSource = dataTable;
gvd2.DataBind();
// Create a document.
using (DocX document = DocX.Create(#"D:\Test.docx"))
{
// Add a Table to this document.
Novacode.Table t = document.AddTable(2, 3);
// Specify some properties for this Table.
t.Alignment = Alignment.center;
t.Design = TableDesign.MediumGrid1Accent2;
// Add content to this Table.
t.Rows[0].Cells[0].Paragraphs.First().Append("A");
//foreach (DataRow row in dataTable.Rows)
//{
// t.Rows[1].Cells[0].Paragraphs.First().Append(row["IssueSubjectType"].ToString());
//}
// Loop through the rows in the Table and insert data from the data source.
for (int row = 1; row < t.RowCount; row++)
{
for (int cell = 0; cell < t.Rows[row].Cells.Count; cell++)
{
Paragraph cell_paragraph =t.Rows[row].Cells[cell].Paragraphs[0];
cell_paragraph.InsertText(dataTable.Rows[row - 1].ItemArray[cell].ToString(), false);
}
}
// Insert the Table into the document.
document.InsertTable(t);
// Save the Document.
document.Save();
// Release this document from memory.
document.Dispose();
}
}
private DataTable dataTable = new DataTable();
// method to pull data from database to datatable
public void PullData()
{
using (SqlConnection sqlConn = new SqlConnection("Data Source=.;Initial Catalog=UAE_OG-Interanl;Integrated Security=True"))
{
string sqlQuery = #"SELECT IssueSubjectType from tbl_IssueStoPublicate WHERE IssueNumber = '625' order by IssueSubjectOrder desc";
using (SqlCommand cmd = new SqlCommand(sqlQuery, sqlConn))
{
SqlDataAdapter ds = new SqlDataAdapter(cmd);
ds.Fill(dataTable);
}
}
}
Any help would be a lifesaver.
https://github.com/xceedsoftware/DocX/blob/master/Examples/Samples/Table/TableSample.cs
int size = 3;
DocX docX = DocX.Create(result, DocumentTypes.Document);
Table table = docX.AddTable(size, size);
table.AutoFit = AutoFit.Contents;
for (int i = 0; i <= (int)TableBorderType.InsideV; i++)
table.SetBorder((TableBorderType)i, new Border());
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
table.Rows[i].Cells[j].Paragraphs[0].InsertText(i + " | " + j);
docX.InsertParagraph().InsertTableBeforeSelf(table);
docX.Save();

Update Row using SqlDataAdapter not working

I wrote this function for updating one single row (I store the information in a class T):
public void Update(T model)
{
if (!Exist(model))
{
throw new Exception("Object Not Found");
}
DataRow row = Convert(model);
row.Table.Rows.Add(row);
row.AcceptChanges();
row.SetModified();
_dataAdapter.Update(new[] { row });
}
(The DataRow comes detached)
the SqlDataAdapter is configured as so:
SqlDataAdapter da = new SqlDataAdapter("Select * From " + tableName,
ConnectedDAL.GetConnection());
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
For some reason my insert and delete work, but the update does not.
The call to Update() completes without errors but the database does not receive the updates.
Help?
Update
The update command text from the command builder is wierd:
For cities (CityID, CityName, CountryID)
"Update [Cities] Set [CityName] = #p1, [CountryID] = #p2 WHERE (([CityID] = #p3 AND ([CityName] = #p4) AND ([CountryID] = #p5))
The first condition makes sense but the rest don't. Also the call returns 1, meaning the it thinks it made the changes.
I have a way to make it work.
public void Update(T model)
{
if (!Exist(model))
{
throw new Exception("Object Not Found");
}
DataRow tmp = GetRow(model);
_dataAdapter.Update(new []{ tmp });
}
private DataRow GetRow(T model)
{
DataRow row = Convert(model);
var schem = Schema;
string[] keys = new string[schem.PrimaryKey.Length];
for (var i = 0; i < schem.PrimaryKey.Length; i++)
{
DataColumn column = schem.PrimaryKey[i];
keys[i] = row[column.ColumnName].ToString();
}
DataRow dr = Convert(Select(keys));
dr.Table.Rows.Add(dr);
dr.AcceptChanges();
for (var i = 0; i < row.ItemArray.Length; i++)
{
if (!schem.Columns[i].AutoIncrement)
{
dr[i] = row.ItemArray[i];
}
}
return dr;
}
This works.

Displaying data in a datagrid

I am trying to display these xml strings in a datagrid. I don't know much about datasets, but it does not seem to keep the data previously entered. Here is my code.
C#:
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string rdr = reader[i].ToString();
dataList.Add(rdr);
string column = reader.GetName(i);
const string xmlAttributeFormat = "{0} = \"{1}\" ";
xmlString = xmlString + String.Format(xmlAttributeFormat, column, dataList[i]);
}
string FinalXMLString = "<row " + xmlString + " />";
StringReader streamreader = new System.IO.StringReader(FinalXMLString);
XmlTextReader xmlreader = new System.Xml.XmlTextReader(streamreader);
dataSet = new System.Data.DataSet();
dataSet.ReadXml(xmlreader);
xmlString = "";
dataList.Clear();
FinalXMLString = "";
}
I have a while loop that is going through the query and then a for loop to put the values in a list. This is working perfectly. The data is then being put into a dataset which is then binded to the datagrid. The only problem is it only shows the data from the last line read from the query. How do I make it show all of the rows from the query in the datagrid? Any help would be appreciated. Thanks in advanced.
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string rdr = reader[i].ToString();
dataList.Add(rdr);
string column = reader.GetName(i);
}
}
Display_Grid(myGrid,dataList)
public static void Display_Grid(DataGrid d, List<string> S1)
{
ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
DataColumn cl = new DataColumn(column, typeof(string));
cl.MaxLength = 200;
dt.Columns.Add(cl);
int i = 0;
foreach (string s in S1)
{
DataRow rw = dt.NewRow();
rw["Description"] = S1[i];
i++;
}
d.ItemsSource = ds.Tables[0].AsDataView();
}
you pass the name of your datagrid (d) and the string List (s1) as parameters ad inside the code you define the name of the columhn header of to be shown (I have written Description).
In your case S1=datalist.
if datalist contains e.g 3 elements then the method will iterate through those and produce 3 rows...

How to add multiple series to the dynamic chart

I put my all code and trying to create a dynamic chart which series comes from database,i looped through listitem collection and trying to populate series and add to the chart.However even i loop through ("#Plant2", DT.Rows[i][0].ToString()); Plant2 and trying to populate multiple series with
plantseries = DT.Rows[i][0].ToString();
Chart1.Series.Add(plantseries);
and then give series the X and Y valuemembers.Finally i can not get all the series in my chart,result indicates last same values for all items in the loop,like my code overwrites the last value onto the same series name.Please help me,i am lost.
string[] lstBox = HiddenField2.Value.Split(seperator, StringSplitOptions.RemoveEmptyEntries);
ListItemCollection lstItemCollection = new ListItemCollection();
for (int i = 0; i < lstBox.Length; i++)
{
lstItemCollection.Add(new ListItem(lstBox[i]));
}
DataTable DT = new DataTable();
DT.Columns.Add("Plant");
foreach (ListItem item in lstItemCollection)
{
DataRow dr = DT.NewRow();
dr["Plant"] = item.Value;
DT.Rows.Add(dr);
}
String plantseries = "";
Chart1.Legends.Add("Plants");
LegendItem legendItem = new LegendItem();
for (int i = 0; i < lstItemCollection.Count; i++)
{
DataTable monthlychart = new DataTable();
if (cnn.State == ConnectionState.Closed)
{
cnn.Open();
SqlCommand cmd1 = new SqlCommand("prc_Chart_individual_plant", cnn);
cmd1.CommandType = System.Data.CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#Plant", strPlants.ToString());
cmd1.Parameters.AddWithValue("#Configuration", strconfig.ToString());
cmd1.Parameters.AddWithValue("#Startdate", dtstart);
cmd1.Parameters.AddWithValue("#Enddate", dtend);
cmd1.Parameters.AddWithValue("#Plant2", DT.Rows[i][0].ToString());
SqlDataAdapter adapt1 = new SqlDataAdapter(cmd1);
adapt1.Fill(monthlychart);
Chart1.DataSource = monthlychart;
cnn.Close();
}
plantseries = DT.Rows[i][0].ToString();
Chart1.Series.Add(plantseries);
Chart1.Series[plantseries].XValueMember = Convert.ToString(monthlychart.Columns[4]);
Chart1.Series[plantseries].YValueMembers = Convert.ToString(monthlychart.Columns[8]);
Chart1.DataBind();
legendItem.Name = plantseries;
legendItem.BorderWidth = 4;
legendItem.ShadowOffset = 1;
Random random = new Random();
Color c = Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
legendItem.Color = c;
Chart1.ChartAreas[0].AxisX.LabelStyle.Format = "M.yy";
Chart1.Series[plantseries].IsVisibleInLegend = true;
Chart1.Series[plantseries].IsValueShownAsLabel = true;
Chart1.Series[plantseries].ToolTip = "Data Point Y Value: #VALY{G}";
}
This is the best approac and it works
for(int j=0; j<monthlychart.Rows.Count; j++)
{
if(monthlychart.Rows[j][4]!=DBNull.Value)
{
DateTime xvalue = Convert.ToDateTime(monthlychart.Rows[j][4]);
double yvalue = Convert.ToDouble(monthlychart.Rows[j][8]);
Chart1.Series[plantseries].Points.AddXY(xvalue,yvalue);
Chart1.DataBind();
}
}

Categories

Resources