I'm using a (Telerik) RadListView (Telerik.WinControls.UI.RadListView()) in my project.
The listview has a few columns:
public MainForm()
{
Telerik.WinControls.UI.ListViewDetailColumn newColumn;
InitializeComponent();
newColumn = new ListViewDetailColumn("ID", "ID");
newColumn.Width = 250;
newColumn.Visible = false;
this.MyListView.Columns.Add(newColumn);
newColumn = new ListViewDetailColumn("Name", "Name");
newColumn.Width = 250;
newColumn.Visible = true;
this.MyListView.Columns.Add(newColumn);
newColumn = new ListViewDetailColumn("Description", "Description");
newColumn.Width = 250;
newColumn.Visible = true;
this.MyListView.Columns.Add(newColumn);
newColumn = new ListViewDetailColumn("Costs", "Costs");
newColumn.Width = 250;
newColumn.Visible = true;
this.MyListView.Columns.Add(newColumn);
I'm populating the listview manually by adding ListViewDataItems to it:
foreach (Data.Tablename listEntry in ListOfTableEntries)
{
ListViewDataItem newRow = new ListViewDataItem(listEntry.Id, new string[]{ listEntry.Name, listEntry.Description, listEntry.Costs});
this.MyListView.Items.Add(newRow);
}
So far so good. What I did not find out though is how I can format specific columns that are making up the added row. For example: Right-align the costs.
How can I do that (without also right-aligning all other columns)?
Thanks
Try something along these lines:
private void radListView1_CellFormatting(object sender, ListViewCellFormattingEventArgs e)
{
if ((e.CellElement).Data.HeaderText == "ID")
{
if ((e.CellElement is DetailListViewDataCellElement))
{
e.CellElement.TextAlignment = ContentAlignment.TopRight;
}
}
if ((e.CellElement).Data.HeaderText == "Name")
{
if ((e.CellElement is DetailListViewDataCellElement))
{
e.CellElement.TextAlignment = ContentAlignment.MiddleCenter;
}
//end so on
}
}
Related
I am working on C#. I use this code copied from the link below to show multi-layered column headers to DataGridView.
DataGridView – Stacked Header
I succeeded to show multi-layered col header itself, but I can't add rows under the column headers. Instead, I got the added rows to be appeared in the col headers that are automatically created besides the multi-layered column headers.
private void Form1_Load(object sender, EventArgs e)
{
DataGridView dgv = dataGridView_syukei;
StackedHeaderDecorator objREnderer = new StackedHeaderDecorator(dgv);
dgv.Columns.Add("Name", "a.Name");
dgv.Columns.Add("1", "a.Id");
List<TestClass> testClasses = new List<TestClass>();
TestClass testClass1 = new TestClass();
testClass1.Id = 1;
testClass1.Name = "John";
TestClass testClass2 = new TestClass();
testClass2.Id = 2;
testClass2.Name = "Mike";
testClasses.Add(testClass1);
testClasses.Add(testClass2);
dgv.DataSource = testClasses;
}
class TestClass
{
public string Name { get; set; }
public int Id { get; set; }
}
Adding AutoGenerateColumns = false and DataPropertyName soloved this problem.
private void Form1_Load(object sender, EventArgs e)
{
DataGridView dgv = dataGridView_syukei;
dgv.AutoGenerateColumns = false;
StackedHeaderDecorator objREnderer = new StackedHeaderDecorator(dgv);
DataGridViewColumn dataGridViewColumn_Name = new DataGridViewColumn();
dataGridViewColumn_Name.HeaderText = "a.Name";
dataGridViewColumn_Name.DataPropertyName = "Name";
dataGridViewColumn_Name.CellTemplate = new DataGridViewTextBoxCell();
dgv.Columns.Add(dataGridViewColumn_Name);
DataGridViewColumn dataGridViewColumn_Id = new DataGridViewColumn();
dataGridViewColumn_Id.HeaderText = "a.Id";
dataGridViewColumn_Id.DataPropertyName = "Id";
dataGridViewColumn_Id.CellTemplate = new DataGridViewTextBoxCell();
dgv.Columns.Add(dataGridViewColumn_Id);
List<TestClass> testClasses = new List<TestClass>();
TestClass testClass1 = new TestClass();
testClass1.Id = 1;
testClass1.Name = "John";
TestClass testClass2 = new TestClass();
testClass2.Id = 2;
testClass2.Name = "Mike";
testClasses.Add(testClass1);
testClasses.Add(testClass2);
dgv.DataSource = testClasses;
}
Can you help me with this. I have this code that will show the output that every time user enter the code it will list down the details. I want to do this add new row into data grid from the code behind (Its the requirement). but apparently, when I add new data, it will also add the new column with the same data again (yes obviously because of my code) but I didn't know how to do it without adding the same column.
this is the code behind
var col = new DataGridTextColumn();
col.Width = 200;
col.Header = "Barcode";
col.IsReadOnly = true;
col.Binding = new Binding("ItemCode");
dgItemDisplay.Columns.Add(col);
var col2 = new DataGridTextColumn();
col2.Width = 400;
col2.IsReadOnly = true;
col2.Header = "Item Name";
col2.Binding = new Binding("ItemName");
dgItemDisplay.Columns.Add(col2);
var col3 = new DataGridTextColumn();
col3.Width = 200;
col3.IsReadOnly = true;
col3.Header = "Item Price";
col3.Binding = new Binding("ItemPrice");
dgItemDisplay.Columns.Add(col3);
if I didn't put this code (dgItemDisplay.Columns.Add(col3);) the data didn't appear in the data grid.
this is my data grid in .xaml
<DataGrid MouseLeftButtonUp="DgItemDisplay_MouseLeftButtonUp" HorizontalAlignment="Center" Width="1096" Name="dgItemDisplay" AutoGenerateColumns="False" Height="auto" SelectionMode="Single" CanUserAddRows="false" SelectionUnit="FullRow" />
I'm sorry if the explanation quite messy. I don't know how to explain it :(
my code for user insert the ItemCode.
private void txtItemCode_KeyDown(object sender, KeyEventArgs e)
{
try
{
string itemCode = txtItemCode.Text;
if (e.Key == Key.Return)
{
SimpleItem item = cashierViewModel.validateItemOnHandCode(txtItemCode.Text, 1);
if (item != null)
{
cashierViewModel.AddItemToList(item, PosWindows2.cashier.ShopId);
LoadData();
dgItemDisplay.ItemsSource = null;
dgItemDisplay.ItemsSource = CashierViewModel.itemDisplayList;
DataGridTextColumn col = new DataGridTextColumn();
col.Width = 200;
col.Header = "Barcode";
col.IsReadOnly = true;
col.Binding = new Binding("ItemCode");
dgItemDisplay.Columns.Add(col);
DataGridTextColumn col2 = new DataGridTextColumn();
col2.Width = 400;
col2.IsReadOnly = true;
col2.Header = "Item Name";
col2.Binding = new Binding("ItemName");
dgItemDisplay.Columns.Add(col2);
DataGridTextColumn col3 = new DataGridTextColumn();
col3.Width = 200;
col3.IsReadOnly = true;
col3.Header = "Item Price";
col3.Binding = new Binding("ItemPrice");
dgItemDisplay.Columns.Add(col3);
spItemDisplay.Children.Add(dgItemDisplay);
}
else
{
MessageBox.Show("Item Not Available.", "Alert", MessageBoxButton.OK, MessageBoxImage.Information);
}
txtItemCode.Text = null;
}
}
catch (Exception ex)
{
CustomExceptionHandling customExceptionHandling = new CustomExceptionHandling();
customExceptionHandling.CustomExHandling(ex.ToString());
}
}
when the user insert the item code in the textbox and press the keydown it will send the details of the item code in the stackpanel.
Could you tell me if you are doing the intended result by having one of the methods below done?
A. Write the following code in the constructor (or OnApplyTemplate) and comment out the corresponding part in "txtItemCode_KeyDown".
var col = new DataGridTextColumn ();
...
dgItemDisplay.Columns.Add (col3);
B. Write a field variable such as bool isColumnAdded = false; in the class.And change inside "txtItemCode_KeyDown" as follows.
if (!isColumnAdded)
{
isColumnAdded = true;
var col = new DataGridTextColumn ();
...
dgItemDisplay.Columns.Add (col3);
}
The DataGrid.Columns.Add method is a method to increase the column of the DataGrid on the UI.
Once the ItemCode, ItemName, ItemPrice columns are displayed, the columns will remain visible.
(I'm sorry if you understood it already.)
I need to populate a DataGridView with items from a List.
I need the first row of the GridView populated with the items from the String List and i need to do some processing on the items in the GridView one by one and add the result to the second row(String).
Currently im Binding the DataGridView like this
dataGridView1.DataSource = mylist.ConvertAll(x => new { Value = x });
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
I need to predefine the column name add strings in the first row,process these strings one by one and update the second column..what is the best way to do this?
here is your solution,
dgvDataViewer.ColumnCount = 1;
dgvDataViewer.Columns[0].Name = "Language";
string[] row = new string[] { "C#" };
dgvDataViewer.Rows.Add(row);
row = new string[] { "C++" };
dgvDataViewer.Rows.Add(row);
row = new string[] { "C" };
dgvDataViewer.Rows.Add(row);
DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
cmb.HeaderText = "HeaderText";
cmb.Name = "Name";
cmb.FlatStyle = FlatStyle.System;
dgvDataViewer.Columns.Add(cmb);
DataGridViewComboBoxCell dgvcbc = (DataGridViewComboBoxCell)dgvDataViewer.Rows[0].Cells[1];
dgvcbc.Items.Add("Apple");
dgvcbc.Items.Add("Google");
dgvcbc.Items.Add("Apache");
dgvcbc.Items.Add("Microsoft");
Hope this will help you for your solution.
First you need to build your columns either programmatically or you can use the designer - that is up to you. I will code all of it for the sake of showing the entire example:
private DataGridView dgNew;
public MyForm()
{
InitializeComponent();
MyInitializeComponent();
}
private void MyInitializeComponent()
{
dgNew = new DataGridView();
var txtCol = new DataGridViewTextBoxColumn
{
HeaderText = "Column1",
Name = "Column1",
DataPropertyName = "Value"
};
dgNew.Columns.Add(txtCol);
txtCol = new DataGridViewTextBoxColumn
{
HeaderText = "Column2",
Name = "Column2",
};
dgNew.Columns.Add(txtCol);
var listOfStrings = new List<string> {"one", "two", "three"};
dgNew.DataSource = listOfStrings.ConvertAll(x => new { Value = x }); ;
dgNew.Location = dg.Location;
dgNew.Parent = this;
this.Load += Form_Load;
}
private void Form_Load(object sender, EventArgs e)
{
// Iterate over the rows, ignoring the header row
foreach (var row in dgNew.Rows.OfType<DataGridViewRow>().Where(a => a.Index != -1))
{
var col1Value = row.Cells["Column1"].Value?.ToString();
var col2Cell = row.Cells["Column2"];
if (col1Value == null) continue;
switch (col1Value)
{
case ("one"):
col2Cell.Value = "row1, col2 val";
break;
case ("two"):
col2Cell.Value = "row2, col2 val";
break;
case ("three"):
col2Cell.Value = "row1, col3 val";
break;
}
}
}
I am trying to View a report dynamically from code behind. But when the parameters are changed from dynamic textboxes added in the page. in the report refresh() the data is not changed.
I call sqlDS() and reportBuild() in the !IsPostback.
This method is for defining the sqlDatasource:
protected void sqlDS()
{
string conString, prName = "";
int counter = 0;
Reporting rep = new Reporting();
rep = rep.searchReport(repID_HF.Value);
Reporting repFold = new Reporting();
repFold = repFold.searchFolder(foldID_HF.Value);
if (repFold.FolderName.Split('(')[1] == "Web Reports)")
{
conString = dbSql.connectionStringAll;
prName = dbSql.providerName;
}
else
{
conString = db.connectionStringAll;
prName = db.providerName;
}
SqlDataSource1.ConnectionString = conString;
SqlDataSource1.ProviderName = prName;
string sqlString = System.IO.File.ReadAllText(Server.MapPath("~/Reports/SQLs/" + rep.SqlFile));
sqlString.Replace(System.Environment.NewLine, " ");
SqlDataSource1.SelectCommand = sqlString;
SqlDataSource1.CancelSelectOnNullParameter = false;
Reporting repParam = new Reporting();
allPs = repParam.getAllParamRep(rep.RepID);
foreach (Reporting itemParam in allPs)
{
if (itemParam.ParamType == "Date")
{
SqlDataSource1.SelectParameters.Add(":" + itemParam.ParamName, itemParam.ParamDefaultValue);
counter++;
}
else if (itemParam.ParamType == "Text")
{
SqlDataSource1.SelectParameters.Add(":" + itemParam.ParamName, itemParam.ParamDefaultValue);
counter++;
}
else if (itemParam.ParamType == "Menu")
{
counter++;
}
}
}
This method is for declaring the report properties:
protected void reportBuild()
{
Reporting rep2 = new Reporting();
rep2 = rep2.searchReport(repID_HF.Value);
ReportViewer1.LocalReport.ReportPath = "Reports/RDLC/" + rep2.RdlcFile;
this.ReportViewer1.LocalReport.ReportEmbeddedResource = rep2.RdlcFile;
ReportParameter[] paramss = new ReportParameter[SqlDataSource1.SelectParameters.Count];
for (int i = 0; i < SqlDataSource1.SelectParameters.Count; i++)
{
paramss[i] = new ReportParameter(SqlDataSource1.SelectParameters[i].Name.Split(':')[1], SqlDataSource1.SelectParameters[i].DefaultValue);
}
ReportDataSource rds = new ReportDataSource(rep2.DatasetName.Split('.')[0], SqlDataSource1);
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(rds);
//paramss[0] = new ReportParameter("TDATE", SqlDataSource1.SelectParameters[0].DefaultValue);
//paramss[1] = new ReportParameter("CUST_NUM", SqlDataSource1.SelectParameters[1].DefaultValue);
ReportViewer1.LocalReport.SetParameters(paramss);
ReportViewer1.LocalReport.Refresh();
}
In the reportViewer refresh method i try to set the new parameters according to the dynamic textboxes added in the page:
protected void ReportViewer1_ReportRefresh(object sender, System.ComponentModel.CancelEventArgs e)
{
foreach (Control txt in Panel1.Controls)
{
if (txt is TextBox)
{
txts.Add(txt);
}
}
foreach (TextBox txtbox in txts)
{
Reporting repP = new Reporting();
repP = repP.searchParam(txtbox.Attributes["pID"].ToString());
if (repP.ParamType == "Date")
{
SqlDataSource1.SelectParameters[":" + repP.ParamName].DefaultValue = txtbox.Text;
}
else if (repP.ParamType == "Text")
{
SqlDataSource1.SelectParameters[":" + repP.ParamName].DefaultValue = txtbox.Text;
}
}
//Reporting r = new Reporting();
//r = r.searchReport(repID_HF.Value);
//Reporting rep = new Reporting();
//rep = rep.searchReport(repID_HF.Value);
//ReportDataSource rds = new ReportDataSource(rep.DatasetName.Split('.')[0], SqlDataSource1);
//this.ReportViewer1.Reset();
//ReportViewer1.LocalReport.DataSources.Clear();
//ReportViewer1.LocalReport.DataSources.Add(rds);
ReportParameterInfoCollection x = ReportViewer1.LocalReport.GetParameters();
//Response.Redirect(Request.RawUrl);
ReportViewer1.LocalReport.Refresh();
}
I tried debugging and found every thing is working correctly the SQL parameters changed, the Report Parameters also is changed.
so why the data in the report is not changed? Plz help me
I got a better and easier way to solve this problem using this link
http://www.igregor.net/post/2007/12/Adding-Controls-to-an-ASPNET-form-Dynamically.aspx
And you can use array of strings to pass attributes.
I've asked this before, but sadly I'm still having issues and the issue wasn't resolved. Basically, I'm dynamically creating a LinkButton for each row of a table I am generating, and that button has the task of deleting the row with the corresponding ID from the database. To do this, I seemingly need to assign the LinkButton a Command so it'll go into the event when it is clicked. Problem is, when the button's clicked the program never goes into the command - I've put breakpoints in there and it never goes into them. Here's my code:
protected void Page_Init(object sender, EventArgs e)
{
if (Request.QueryString["id"] != null)
{
ColorConverter conv = new ColorConverter();
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
TPRDBDataContext dc = new TPRDBDataContext();
DataContext db = new DataContext(connection);
Table<SageAccount> SageAccount = db.GetTable<SageAccount>();
Table<InvoiceItem> InvoiceItem = db.GetTable<InvoiceItem>();
Table<Invoice> Invoice = db.GetTable<Invoice>();
Boolean alloweditting = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.alloweditting).Single();
if (alloweditting == false)
{
dtlsInsert.Visible = false;
modalPanel.Visible = false;
}
int sagepk = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s.sageaccount).Single();
lblSageID.Text = (from s in dc.SageAccounts where s.ID == sagepk select s.SageID).Single();
lblDate.Text = DateTime.Now.ToShortDateString();
Table table = new Table();
table.Width = Unit.Percentage(100);
table.GridLines = (GridLines)3;
TableHeaderRow header = new TableHeaderRow();
header.BackColor = (System.Drawing.Color)conv.ConvertFromString("#EDEDED");
foreach (string header2 in new string[] { "", "Quantity", "Rate", "Description", "Nominal Code", "Subtotal" })
{
TableCell cell = new TableCell();
cell.Text = header2;
header.Cells.Add(cell);
}
table.Rows.Add(header);
var data = (from s in dc.InvoiceItems where s.invoiceid.ToString() == Request.QueryString["id"].ToString() select s);
foreach (var x in data)
{
TableRow row = new TableRow();
if (x.invoicetext == null)
{
decimal total;
try
{
total = (decimal)x.rate * (decimal)x.quantity;
}
catch
{
total = 0;
}
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.quantity.ToString(), x.rate.ToString(), x.description, x.nominalcode, total.ToString("N2") })
{
TableCell cell = new TableCell();
{
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
lnkdel.CommandArgument = x.id.ToString();
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
}
}
row.Cells.Add(cell);
}
runningtotal = runningtotal + total;
}
else
{
int i = 0;
foreach (string columnData in new string[] { x.id.ToString(), x.invoicetext })
{
TableCell cell = new TableCell();
if (i == 0)
{
LinkButton lnkdel = new LinkButton();
lnkdel.Text = "Delete";
lnkdel.ID = "lnkDel" + Guid.NewGuid();
if (alloweditting == false)
{
lnkdel.Enabled = false;
}
lnkdel.Font.Bold = false;
//lnkdel.Command += lnkdel_Command;
//lnkdel.Command += new CommandEventHandler(this.lnkdel);
lnkdel.CommandArgument = x.id.ToString();
cell.Controls.Add(lnkdel);
i++;
}
else
{
cell.Text = columnData;
cell.ColumnSpan = 5;
}
row.Cells.Add(cell);
}
}
switch (x.formatoptions)
{
case 1:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = false;
break;
case 2:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("black");
row.Font.Bold = true;
break;
case 3:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = false;
break;
case 4:
row.ForeColor = (System.Drawing.Color)conv.ConvertFromString("red");
row.Font.Bold = true;
break;
}
table.Rows.Add(row);
}
TableFooterRow row2 = new TableFooterRow();
TableCell cell2 = new TableCell();
cell2.Text = "<span style\"text-align: right; width: 100%;\">Total = <b>" + runningtotal.ToString("N2") + "</b></span>";
cell2.ColumnSpan = 6;
row2.Cells.Add(cell2);
table.Rows.Add(row2);
var update = (from s in dc.Invoices where s.id.ToString() == Request.QueryString["id"] select s).Single();
update.total = runningtotal;
dc.SubmitChanges();
datatable.Controls.Clear();
datatable.Controls.Add(table);
}
else
{
Response.Redirect("Invoices.aspx");
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lnkdel_Command(object sender, CommandEventArgs e)
{
string connection = ConfigurationManager.ConnectionStrings["TPRTestConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connection))
{
SqlCommand comm = new SqlCommand("DELETE FROM InvoiceItem WHERE id = #id", conn);
comm.Parameters.AddWithValue("#id", e.CommandArgument.ToString());
conn.Open();
try
{
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
Response.Write(ex);
}
}
}
Note I've commented out 2 of the crucial lines for posting here, just to point out that I've tried both of the lines that's commented out, and neither work :(
You need to add the controls on every postback. You appear to be only creating them on the initial get (that query string check). On the post back, those controls never get recreated so no event fires.
It's notoriously counter-intuitive, but while ASP.NET bends over backwards to make you think that the instance of your page class is the same between two HTTP requests, the reality is that they are not the same. A new instance is created each time. It looks like you are trying to avoid adding the dynamically generated controls multiple times -- thinking you don't want duplicates. The reality is that you will never get duplicates when adding dynamically generated controls in a life-cycle method such as OnInit() since it's always a new instance of the page class, and thus those dynamically generated controls are gone.
The reason this is usually transparent to developers is that all the controls in the code-front are automatically re-generated for you on both the initial request and every single post-back. For your dynamically created controls, you happen to have this line:
if (Request.QueryString["id"] != null) { ... }
Unless you're doing something special, that "id" attribute will not be in the query string on the postback. This means that none of the code in the if block will be run on the post back (when your event actually fires.) This means that your if-check at the top should be removed altogether. All that code should run for each and every request (GET and POST).
Just saying I've created a workaround - simply creating a simple link to the page, along with a query string containing the id of the row to delete