I have a "time duration" column in a grid view, and I wish to sum that particular column in C# and publish the total time taken at a label named Total Time. How can I do this?
Sample code:
int sum = 0;
for (int i = 0; i < dgTestSteps.SelectedColumns.Count; ++i)
{
sum += Convert.ToInt32(dgTestSteps.SelectedColumns.Count.ToString());
//sum += Convert.ToInt32(dgTestSteps.Rows[i].Cells[1].Value);
}
lblTotalTime.Text = sum.ToString();
int sum = 0;
for (int i = 0; i < dgTestSteps.Rows.Count; ++i)
{
sum += Int.Parse(dgTestSteps.Rows[i].Cells[1].Value.ToString());
}
lblTotalTime.Text = sum.To String();
It seems true! Is there any problem with this?
I do this by aggregating the column row values in a class variable thusly:
Code behind:
protected void ItemsGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Get the row variable values
var rowView = (DataRowView)e.Row.DataItem;
var itemId = Convert.ToInt32(rowView["ItemID"]);
var skuId = Convert.ToInt32(rowView["ItemSkuID"]);
var quantity = Convert.ToInt32(rowView["Quantity"]);
// Instantiate instances of the relevant classes
var item = new Item(itemId);
var sku = new Sku(skuId);
var itemPrice = String.Format("{0:n2}", (item.Price + sku.PriceAdj));
var itemPriceLiteral = (Literal)e.Row.FindControl("ItemPrice");
if (itemPriceLiteral != null)
{
itemPriceLiteral.Text = itemPrice;
}
var itemExtendedPriceLiteral = (Literal)e.Row.FindControl("ItemExtendedPrice");
if (itemExtendedPriceLiteral != null)
{
var extendedPrice = price * quantity;
itemExtendedPriceLiteral.Text = String.Format("{0:n2}", extendedPrice);
// Increment the extended price
_totalExtendedPrice += extendedPrice;
}
}
}
// Lots of stuff omitted from this method for clarity
public void GetSummary()
{
// Set the text property of the total literal below the GridView
OrderTotal.Text = string.Format((HttpUtility.HtmlDecode(
(string)GetGlobalResourceObject("ShopStrings", "UsdPrice"))),
_totalExtendedPrice);
}
OrderTotal.Text is localized but you can easily format it without using resources.
You can use this but you should know that number of columns start with 0 and goes up with 1
int sum = 0;
for (int i = 0; i < dgTestSteps.Rows.Count; ++i)
{
sum += Convert.ToInt32(dgTestSteps.Rows[i].Cells[0].Value);
}
lblTotalTime.Text = sum.ToString();
I tried this and has no problem
Related
I have a gridview with multiple groups and I use the CustomDrawGroupRow Event to display the row count for each group:
private void gridView_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e)
{
var view = (GridView)sender;
var info = (GridGroupRowInfo)e.Info;
var caption = info.Column.Caption;
if (info.Column.Caption == string.Empty)
{
caption = info.Column.ToString();
}
info.GroupText = $"{caption} : {info.GroupValueText} ({view.GetChildRowCount(e.RowHandle)})";
}
Now I would like to display the row count recursively, so that the first level shows a count of 2171 (1913 + 135 + 123).
This is what I have tried, but it throws a StackOverflowException and I cannot see the problem here:
private void gridView_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e)
{
var view = (GridView)sender;
var info = (GridGroupRowInfo)e.Info;
var caption = info.Column.Caption;
if (info.Column.Caption == string.Empty)
{
caption = info.Column.ToString();
}
info.GroupText = $"{caption} : {info.GroupValueText} ({GetRowCountRecursive(view, e.RowHandle)})";
}
private int GetRowCountRecursive(GridView view, int rowHandle)
{
int totalCount = 0;
int childrenCount = view.GetChildRowCount(rowHandle);
for (int i = 0; i < childrenCount; i++)
{
var childRowHandle = view.GetChildRowHandle(rowHandle, i);
totalCount += GetRowCountRecursive(view, childRowHandle);
}
return totalCount;
}
I was missing to check if childRowHandle is a group row with IsGroupRow(). If not, the recursion have to stop and totalCount need to be increased by 1.
private int GetRowCountRecursive(GridView view, int rowHandle)
{
int totalCount = 0;
int childrenCount = view.GetChildRowCount(rowHandle);
for (int i = 0; i < childrenCount; i++)
{
var childRowHandle = view.GetChildRowHandle(rowHandle, i);
if (view.IsGroupRow(childRowHandle))
{
totalCount += GetRowCountRecursive(view, childRowHandle);
}
else
{
totalCount++;
}
}
return totalCount;
}
You can use GroupRowInfo.ChildControllerRowCount property to get the row count. The instance of GroupRowInfo class you can get from GridGroupRowInfo.RowKey property.
Here is example:
private void gridView1_CustomDrawGroupRow(object sender, RowObjectCustomDrawEventArgs e)
{
var view = (GridView)sender;
var info = (GridGroupRowInfo)e.Info;
var caption = info.Column.Caption;
if (info.Column.Caption == string.Empty)
{
caption = info.Column.ToString();
}
var groupInfo = info.RowKey as GroupRowInfo;
info.GroupText = $"{caption} : {info.GroupValueText} ({groupInfo?.ChildControllerRowCount})";
}
Here is the screenshot:
I am trying to populate TextBoxes from a list. I have been able to populate ComboBoxes with comboList:
var comboList = new System.Windows.Forms.ComboBox[4];
comboList[0] = cmbSite1Asset;
comboList[1] = cmbSite2Asset;
comboList[2] = cmbSite3Asset;
comboList[3] = cmbSite4Asset;
List<CRCS.CAsset> assets = _rcs.Assets;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int i = 0; i < 4; ++i)
{
comboList[i].Items.Add(id);
}
}
But when I try and apply the same principle to TextBoxes
var aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int n = 0; n < 8; ++n)
{
aosList[n].Items.Add(id);
}
}
TextBox does not like Items.Add ( aosList[n]Items.Add(id); )
I am looking fore a reference or guidance resolving this issue. Thanks!
You should use ComboBox for your problem,instead of iterating on each element,You simply use below lines to populate combobox.
comboList.DataSource=assets;
comboList.DisplayMember="ID";
comboList.ValueMember="ID";
However,if you want your values in TextBox,you can use TextBox.AppendText Method, but it will not work like ComboBox as it will contain texts+texts+texts, will not have indexes like ComboBox.
private void AppendTextBoxLine(string myStr)
{
if (textBox1.Text.Length > 0)
{
textBox1.AppendText(Environment.NewLine);
}
textBox1.AppendText(myStr);
}
private void TestMethod()
{
for (int i = 0; i < 2; i++)
{
AppendTextBoxLine("Some text");
}
}
A Combobox is a collection of items, and so has an Items property from which you can add/remove to change it's contents. A Textbox is just a control that displays some text value, so it has a Text property which you can set/get, and which denotes the string that is displayed.
System.Windows.Forms.TextBox[] aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
for (int n = 0; n < 8; ++n)
{
aosList[n].Text = assets[n].ID; // make sure you have 8 assets also!
}
int i = 1;
foreach (var asset in assets)
{
this.Controls["txtAsset" + i].Text = asset.ID;
i++;
}
i have created a telerik grid for small payment module
in this module i have selected two checkbox and enter a amount,i need the total amount to be displayed in the donation amount label
The current code is to sum up the values displayed in the second column,and saving the values in session and passsing to next page.
Gridview
<telerik:GridTemplateColumn FilterControlAltText="Filter TemplateColumn3 column" UniqueName="TemplateColumn3">
<ItemTemplate>
<asp:TextBox ID="txt_amnt" runat="server"></asp:TextBox> </td>
</ItemTemplate>
</telerik:GridTemplateColumn>
c# code
protected void chk_box_CheckedChanged(object sender, EventArgs e)
{
if (ViewState["dt"].ToString().Trim() != "NULL")
{
dt = (DataTable)ViewState["dt"];
}
if (dt.Columns.Count == 0)
{
dt.Columns.Add("Id");
dt.Columns.Add("Name");
dt.Columns.Add("Amount");
}
CheckBox chk = (CheckBox)sender;
if (chk.Checked == true)
{
dt.Rows.Add();
dt.Rows[dt.Rows.Count-1 ]["Id"] = ((Label)chk.FindControl("lb_id")).Text.Trim();
dt.Rows[dt.Rows.Count - 1]["Name"] = ((Label)chk.FindControl("lb_donation")).Text.Trim();
dt.Rows[dt.Rows.Count - 1]["Amount"] = ((Label)chk.FindControl("lb_amount")).Text.Trim();
// dt.Rows[dt.Rows.Count + 1]["chkstatus"] = ((Label)chk.FindControl("lb_amount")).ToString().Trim();
}
else {
for (int i = 0; i < dt.Rows.Count; i++)
{
if(((Label)chk.FindControl("lb_id")).Text.Trim()==dt.Rows[i]["Id"].ToString().Trim())
{ dt.Rows.RemoveAt(i); }
}
}
ViewState["dt"] = dt;
double tamount = 0;
for (int i2 = 0; i2 < dt.Rows.Count; i2++)
{
tamount = tamount + Convert.ToDouble(dt.Rows[i2]["Amount"]);
}
lb_tamount.Text = tamount.ToString() ;
}
I believe your code for the CheckBox will always hit error.
How can you find a control inside a CheckBox ? Secondly your code is not complete as per the result you are showing. Anyway here is the idea how you can get checked item in your RadGrid.
First you need loop the RadGrid to get all checked CheckBox.
Then sum up the total and put it to the label.
This code just to mock up for your scenario. Please use TryParse to get the int value to ensure no converting error.
Code Behind
protected void chkCheck_CheckedChanged(object sender, EventArgs e)
{
// Variable
int total = 0;
int amt = 0;
int donateAmt = 0;
foreach (GridDataItem item in rg.Items)
{
// Find Control
CheckBox chkCheck = item.FindControl("chkCheck") as CheckBox;
Label lblAmount = item.FindControl("lblAmount") as Label;
TextBox txtAmount = item.FindControl("txtAmount") as TextBox;
// Reset Amount
amt = 0;
donateAmt = 0;
// Check
if (chkCheck != null && chkCheck.Checked)
{
// Check & Get Value
if (lblAmount != null && txtAmount != null)
{
// Check & Set
if (lblAmount.Text.Trim() != string.Empty)
amt = Convert.ToInt32(lblAmount.Text.Trim());
// Check & Set
if (txtAmount.Text != string.Empty)
donateAmt = Convert.ToInt32(txtAmount.Text.Trim());
// Check current Amount in stock and donate amt
if (donateAmt > amt)
{
donateAmt = amt;
txtAmount.Text = donateAmt + "";
}
// Reset to the text
}
total += donateAmt;
}
}
lblTotal.Text = total + "";
}
I'm making a calculator in GUI, and I need some help.
When I enter some data in a text box, I need to store it in an array. This is how I thought of it.
int numOfPackages;//used to get user input
private void button3_Click(object sender, EventArgs e)
{
int[] weight = new int[numOfPackages];
for(int i = 0; i < numOfPackages; i++)
{
weight[i] = Convert.ToInt32(weightBox.Text);
}
foreach (int i in weight)
totalCostLabel.Text = "" + weight[i];
}
And when I try to display the elements, it gives me the indexOutOfRange exception.
So, how do I display the elements of that array?
Thanks in advance.
This line
foreach (int i in weight)
totalCostLabel.Text = "" + weight[i];
should be
foreach (int w in weight)
totalCostLabel.Text = "" + w;
Your current code iterates the array of weights, and tries to use the weight as an index into the array of weights, causing an index out of range exception.
Another problem is with the first loop: you are setting all values of weight to the same number:
weight[i] = Convert.ToInt32(weightBox.Text); // That's the same for all i-s
If weights are to be different, they should come from different weight boxes, or the string from a single weightBox should be processed in such a way as to produce multiple numbers (for example, by using string.Split).
You have multiple problems here. First is this:
foreach (int i in weight)
totalCostLabel.Text = "" + weight[i];
This is iterating the weight array and using each value in that array. You then use that value as an index. Take the following example:
weight[0] = 0
weight[1] = 1
weight[2] = 15
In your code, the first two entries will work because there is an index of 0 and an index of 1. But when it gets to the last entry, it looks for an index of 15. You can fix this two ways, the first is to use a regular for loop:
for(int i=0; i < weight.Length; i++)
{
totalCostLabel.Text += weight[i];
}
This brings the second mistake. You aren't appending anything to your totalCostLabel in your code, you are just replacing the value. This will append all the values of weight together as one.
Another way to do this is to use the foreach loop:
foreach(int i in weight)
{
totalCostLabel.Text += i;
}
This is the same as above but you don't have to worry about indexing.
Bottom line, even after you fix your loop, you will probably need to fix the way that the label takes the text otherwise you won't get your desired result.
Maybe you wanted something more like?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btnAdd.Enabled = false;
}
int[] weight;
int entriesMade;
int numOfPackages;
private void btnReset_Click(object sender, EventArgs e)
{
if (int.TryParse(numEntriesBox.Text, out numOfPackages))
{
weight = new int[numOfPackages];
entriesMade = 0;
btnReset.Enabled = false;
btnAdd.Enabled = true;
totalCostLabel.Text = "";
}
else
{
MessageBox.Show("Invalid Number of Entries");
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
int value;
if (int.TryParse(weightBox.Text, out value))
{
weight[entriesMade] = value;
weightBox.Clear();
totalCostLabel.Text = "";
int total = 0;
for (int i = 0; i <= entriesMade; i++)
{
total = total + weight[i];
if (i == 0)
{
totalCostLabel.Text = weight[i].ToString();
}
else
{
totalCostLabel.Text += " + " + weight[i].ToString();
}
}
totalCostLabel.Text += " = " + total.ToString();
entriesMade++;
if (entriesMade == numOfPackages)
{
btnAdd.Enabled = false;
btnReset.Enabled = true;
MessageBox.Show("Done!");
}
}
else
{
MessageBox.Show("Invalid Weight");
}
}
}
I have been saving into the ComboBox a value out of the selected column in datagridview with below code.
My question is:How can I prevent duplicate records when I save the values into the ComboBox? How can I do that?
Code:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
Please try this
private void dgvServerList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
if (e.ColumnIndex == 1)
{
string id = dgvServerList[e.ColumnIndex, e.RowIndex].Value.ToString();
int duplicaterow = 0;
for (int row = 0; row < dgvServerList.Rows.Count; row++)
{
if (row != e.RowIndex && id == dgvServerList[e.ColumnIndex, row].Value.ToString())
{
duplicaterow = row + 1;
MessageBox.Show("Duplicate found in the row: " + duplicaterow);
this.dgvServerList[e.ColumnIndex, e.RowIndex].Value = "";
break;
}
}
}
}
catch
{
}
}
you could first transfer your datagridview items to a dictionary (which guarantees uniqueness) and then transfer that dictionary content to the combobox. or you could check for uniqueness yourself using a 'Contains' method on the combobox. you could even tie the dictionary to the combobox as a source for the combobox items.
Dictionary<string,bool> d = new Dictionary<string,bool>();
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
d[dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()] = true;
}
CmbAra.Items.AddRange(d.Keys);
Use a set:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
HashSet<string> set = new HashSet<string>();
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
string s = dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString();
if(!set.Contains(s)) {
CmbAra.Items.Add(s);
set.Add(s);
}
}
by using the following check and then determine to add or not
if(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()))
You can use the following code part.
if(!(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString())))
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
else
{
MessageBox.Show("Value Already exists , not added");
}