Acumatica Styling a specific column/cell in PXView? - c#

I am VERY new to Acumatica in coding. I am trying to change the color of a cell on the header page of AR303000. (see code below). Obviously this is not working. I receive the error message of PXFormViewEventArgs does not exist in the namespace PX.Web.UI.
Can anyone direct me as to what namespace I should be using and correct my code to make this work?
Thank you,
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using PX.Common;
using PX.Data;
using PX.SM;
using PX.Objects.AR.CCPaymentProcessing;
using PX.Objects.AR.Repositories;
using PX.Objects.Common;
using PX.Objects.Common.Discount;
using PX.Objects.CA;
using PX.Objects.CM;
using PX.Objects.CR;
using PX.Objects.CR.Extensions;
using PX.Objects.CS;
using PX.Objects.SO;
using PX.Objects.AR.CCPaymentProcessing.Helpers;
using PX.Data.BQL.Fluent;
using PX.Data.BQL;
using PX.Data.Descriptor;
using CashAccountAttribute = PX.Objects.GL.CashAccountAttribute;
using PX.Objects.GL.Helpers;
using PX.Objects.TX;
using PX.Objects.IN;
using PX.Objects.CR.Extensions.Relational;
using PX.Objects.CR.Extensions.CRCreateActions;
using PX.Objects.GDPR;
using PX.Objects.GraphExtensions.ExtendBAccount;
using PX.Data.ReferentialIntegrity.Attributes;
using CRLocation = PX.Objects.CR.Standalone.Location;
using PX.Objects;
using PX.Objects.AR;
namespace PX.Objects.AR
{
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
protected void Page_Load(object sender, EventArgs e)
{
Style escalated = new Style();
escalated.ForeColor = System.Drawing.Color.Red;
this.Page.Header.StyleSheet.CreateStyleRule(escalated, this, ".CssEscalated");
Style rowStyle = new Style();
rowStyle.BackColor = System.Drawing.Color.Red;
this.Page.Header.StyleSheet.CreateStyleRule(rowStyle, this, ".CssRowStyle");
Style cellStyle = new Style();
cellStyle.BackColor = System.Drawing.Color.Aqua;
this.Page.Header.StyleSheet.CreateStyleRule(cellStyle, this, ".CssCellStyle");
Style highlightStyle = new Style();
highlightStyle.BackColor = System.Drawing.Color.Yellow;
this.Page.Header.StyleSheet.CreateStyleRule(highlightStyle, this, ".CssHighlightStyle");
}
protected void Customer_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PX.Web.UI.PXFormViewEventArgs f)
{
var customer = (CR.BAccount)e.Row;
var customerExt = customer.GetExtension<CR.BAccountExt>();
if (customerExt != null)
{
/*I want to change the color of this cell in the form*/
customerExt.UsrReadOnlyAcctName = customer.AcctName;
}
}
#region Event Handlers
#endregion
}
}```

I think you can detect the Form and the control of the UsrReadonlyAcctName and then apply the Css style during Page_Load; below is an example, but in my case, I find a Grid and then detect a Cell's value during RowDataBound:
public override void Initialize()
{
//Access page via http context current handler
Page page = HttpContext.Current?.Handler as PXPage;
if (page != null)
{
page.Load += Page_Load;
}
}
private void Page_Load(object sender, EventArgs e)
{
Page page = (Page)sender;
RegisterStyle(page, "MyCssRed", "#FD9999 !important", null, false);
PX.Web.UI.PXGrid grdMyGridControl = (PX.Web.UI.PXGrid)ControlHelper.FindControl("grid2", page); // Allocations popup
if (grdMyGridControl != null)
{
grdMyGridControl.RowDataBound += (object grdsender, PXGridRowEventArgs erdb) =>
{
var data = erdb.Row;
if (data == null) { return; }
bool isRed = false;
PXGridCell cell = data.Cells["INItemLotSerialKvExt__ValueString"];
if (cell == null) return;
Object value = cell.Value;
if (value != null && (String)value == "R")
{
isRed = true;
}
...
if (isRed)
data.Style.CssClass = "MyCssRed";
Patrick Chen supplies a helpful reference.
EDIT ANSWER:
Below is an example on the Sales Order page SO301000 that finds the "Customer Order Nbr" TextBox and adds color when its Text is empty:
private void Page_Load(object sender, EventArgs e)
{
Page page = (Page)sender;
RegisterStyle(page, "MyCssRed", "#FD9999 !important", null, false);
PX.Web.UI.PXTextEdit myBox = (PX.Web.UI.PXTextEdit)ControlHelper.FindControl("edCustomerOrderNbr", page);
if (myBox != null)
{
myBox.DataBinding += (object boxsender, EventArgs boxargs) =>
{
PX.Web.UI.PXTextEdit box = boxsender as PX.Web.UI.PXTextEdit;
string cellText = box.Text;
box.CssClass = string.IsNullOrEmpty(cellText) ? "MyCssRed" : "editor";
};
}

Related

How can i save settings of my app to a text file and read them back on load?

Read them back in app constructor and also maybe in other places in program.
I have a new form i created with some checkboxes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Options
{
public partial class OptionsMenuForm : Form
{
public OptionsMenuForm()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Settings.downloadonstart = true;
}
else
{
Settings.downloadonstart = false;
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
Settings.loadonstart = true;
}
else
{
Settings.loadonstart = false;
}
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
Settings.startminimized = true;
}
else
{
Settings.startminimized = false;
}
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
if (checkBox4.Checked)
{
Settings.displaynotifications = true;
}
else
{
Settings.displaynotifications = false;
}
}
}
}
Now i want to save each time the state of one/any of the checkboxes.
I also added a class i'm using th pass the variables between the new form and form1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Options
{
class Settings
{
public static bool downloadonstart;
public static bool loadonstart;
public static bool startminimized;
public static bool displaynotifications;
}
}
Now how can i use this in form1 by saving the settings to a text file ?
For example in the text file the content will be something like:
CheckBox1 = true
CheckBox2 = false
CheckBox3 = false
CheckBox4 = true
And then if i change the state of one of them it will write it in the text file:
CheckBox1 = false
CheckBox2 = false
CheckBox3 = true
CheckBox4 = true
In form1 top i added
string settingsFile = "settings.txt";
string settingsFileDirectory = "\\settings";
StreamWriter writetosettingsfile;
Then in constructor
settingsFileDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) +
settingsFileDirectory;
if (!Directory.Exists(settingsFileDirectory))
{
Directory.CreateDirectory(settingsFileDirectory);
}
I know the app it self have a settings in the properties but i wanted to use a text file this time since i have many settings and i might have more later.
Or using the settings in the app in properties i did:
But now how do i use with it in my program to save every checkbox state in the new form and then using it in form1 ?
You can use json.net
Something like this to save the data
private void Form1_Load(object sender, EventArgs e)
{
checkBox1.CheckedChanged += checkBox_CheckedChanged;
checkBox2.CheckedChanged += checkBox_CheckedChanged;
checkBox3.CheckedChanged += checkBox_CheckedChanged;
checkBox4.CheckedChanged += checkBox_CheckedChanged;
}
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
var settings = new Settings();
settings.downloadonstart = checkBox1.Checked;
settings.loadonstart = checkBox2.Checked;
settings.startminimized = checkBox3.Checked;
settings.displaynotifications = checkBox4.Checked;
File.WriteAllText(#"c:\configfile.json", JsonConvert.SerializeObject(settings));
}
You can read the file like this
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(#"c:\configfile.json"));
Documentation:
http://www.newtonsoft.com/json/help/html/Introduction.htm
public OptionsMenuForm()
{
InitializeComponent();
//Read the settings from a file with comma delimited 1's and 0's or whatever you like
string[] values = System.IO.File.ReadAllText("c:\temp\a.txt").Split(',');
checkBox1.Checked = Convert.ToBoolean(Convert.ToInt32(values[0]));
checkBox2.Checked = Convert.ToBoolean(Convert.ToInt32(values[1]));;
//On checkbox changes save the settings
checkBox1.CheckedChanged +=SaveSettings;
checkBox2.CheckedChanged +=SaveSettings;
}
public void SaveSettings(object sender,EventArgs e)
{
StringBuilder sbValues = new StringBuilder();
int i = 0;
i = checkBox1.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
i = checkBox2.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
System.IO.File.WriteAllText("c:\temp\a.txt",sbValues.ToString());
}
It is recommended that you use XML when using the .NET framework.
public static void ConvertStringToXmlList()
{
XElement xml = new XElement
(
"Items",
(
from x in [YourList] select new XElement("Item", x)
)
);
XDocument doc = new XDocument
(
xml
);
doc.Save(Environment.CurrentDirectory + "/settings.xml");
}
var xmlReader = new XmlTextReader("settings.xml");
while (xmlReader.Read())
{
switch (reader.NodeType)
{
case [nodetype]:
// Code here
break;
}
}
Also, instead of creating the same event for all four checkbox's, just use 1.
Inside of the single event put:
ckCheckBox1.Checked = !ckCheckBox1.Checked;

Datatable is being overwritten

In an ASP.NET project i have 2 textboxes and a submit button.
In the event handler of button clicked i want to save the values of the textboxes to a datatable and then bind the datatable to a Gridview.
This has to happen multiple times. But every time the datatable has one row, like being overwritten every time the event handler fires. It's like the datatable is being created from the beginning every time the event handler fires. Code below. Thanks for your time.
EDIT: Thanks for all the answers you gave.
protected void BtnInsertCustomerLegalRelationsInsert_Click(object sender, EventArgs e)
{
string FullCompanyName = TbxFullCompanyName.Text.Trim();
object LegalRelationAfm = TbxLegalRelationAfm.Text.Trim();
if (dtCustomersLegalRelations.Columns.Count == 0)
{
dtCustomersLegalRelations.Columns.Add("FullCompanyName",typeof(string));
dtCustomersLegalRelations.Columns.Add("LegalRelationAfm",typeof(string));
}
DataRow dr = dtCustomersLegalRelations.NewRow();
dr["FullCompanyName"] = FullCompanyName;
dr["LegalRelationAfm"] = LegalRelationAfm;
dtCustomersLegalRelations.Rows.Add(dr);
GvCustomerRegalRelations.DataSource = dtCustomersLegalRelations;
GvCustomerRegalRelations.DataBind();
}
The whole code behind here
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
public partial class ConnectedBorrowers_CustomerBasicInput : System.Web.UI.UserControl
{
DataTable dtCustomersLegalRelations = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
TrLegalRelations1.Visible = TrLegalRelations2.Visible = TrLegalRelations3.Visible = false;
}
}
protected void CbMandatoryAFM_CheckedChanged(object sender, EventArgs e)
{
if (CbMandatoryAFM.Checked == true)
{
TbxCustAfm.ReadOnly = true;
TbxCustAfm.BackColor = Color.LightGray;
}
else
{
TbxCustAfm.ReadOnly = false;
TbxCustAfm.BackColor = Color.White;
}
}
protected void CbLegalRelationsMandatoryAFM_CheckedChanged(object sender, EventArgs e)
{
if (CbLegalRelationsMandatoryAFM.Checked == true)
{
TbxLegalRelationAfm.ReadOnly = true;
TbxLegalRelationAfm.BackColor = Color.LightGray;
}
else
{
TbxLegalRelationAfm.ReadOnly = false;
TbxLegalRelationAfm.BackColor = Color.White;
}
}
protected void CbLegalRelations_CheckedChanged(object sender, EventArgs e)
{
if (CbLegalRelations.Checked == true)
{
TrLegalRelations1.Visible = TrLegalRelations2.Visible = TrLegalRelations3.Visible = true;
}
else
{
TrLegalRelations1.Visible = TrLegalRelations2.Visible = TrLegalRelations3.Visible = false;
}
}
protected void BtnInsertCustomerLegalRelationsInsert_Click(object sender, EventArgs e)
{
try
{
string FullCompanyName = TbxFullCompanyName.Text.Trim();
object LegalRelationAfm = TbxLegalRelationAfm.Text.Trim();
if (dtCustomersLegalRelations.Columns.Count == 0)
{
dtCustomersLegalRelations.Columns.Add("FullCompanyName",typeof(string));
dtCustomersLegalRelations.Columns.Add("LegalRelationAfm",typeof(string));
}
DataRow dr = dtCustomersLegalRelations.NewRow();
dr["FullCompanyName"] = FullCompanyName;
dr["LegalRelationAfm"] = LegalRelationAfm;
dtCustomersLegalRelations.Rows.Add(dr);
GvCustomerRegalRelations.DataSource = dtCustomersLegalRelations;
GvCustomerRegalRelations.DataBind();
}
catch (Exception ex)
{
((Label)this.Page.Master.FindControl("LblError")).Text = ex.Message;
}
}
Try such approach:
public partial class ConnectedBorrowers_CustomerBasicInput : System.Web.UI.UserControl
{
DataTable dtCustomersLegalRelations;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dtCustomersLegalRelations = new DataTable();
Session["table"] = dtCustomersLegalRelations;
TrLegalRelations1.Visible = TrLegalRelations2.Visible = TrLegalRelations3.Visible = false;
} else {
dtCustomersLegalRelations = Session["table"] as DataTable;
}
}
...
}
The value of 'dtCustomersLegalRelations' will not persist through PostBack events - so when you add the row on the end of it, you're doing so on a new instance.
You need to fetch all the data back out of the GridView before you add the new row and re-bind it.
st4hoo's answer above should sort it for you.
When u click the button postback occurs. During each postback your datatable is created from the beginning. So u will lose ur old data.
So one option is that u can keep the datatable with data in a session and retrieve the datatable from the session during the next button click and add the new row.
At what point do you create the datatable (dtCustomersLegalRelations)? Could you paste the complete code including the cration of the datatable and the button_click?

I'm trying to change the color of each of a set of buttons using C#/Visual studio but nothing happens

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Cameron_PickerillTrinitapoli_Assn1
{
public partial class seasonalBttnChanger : Form
{
public seasonalBttnChanger()
{
InitializeComponent();
}
//Triggers when program first loads
//Sets up
private void bttnChanger_Load(object sender, EventArgs e)
{
List<Button> lstTxt = new List<Button>
{
bttnSpring, bttnSummer, bttnAutumn, bttnWinter
};
//Wiring up event handlers in run time
foreach (Button txt in lstTxt)
{
txt.MouseEnter += button_MouseEnter;
txt.MouseLeave += button_MouseLeave;
}
}
// Sets up different background colors for TextBoxes
//* Static values for the color of each button need
//to be added.
//**Not what I was trying to accomplish
//**This needs to go somewhere else
void button_MouseEnter(object sender, EventArgs e)
{
try
{
// Event handlers always pass the parameter "sender" in as an object.
// You have to downcast it back to the actual type.
String bttnName = null;
String bttnNameSpring = "Spring";
String bttnNameSummer = "Summer";
String bttnNameAutumn = "Autumn";
String bttnNameWinter = "Winter";
Button txt = (Button)sender;
// stkColor.Push(txt.BackColor);
//txt.BackColor = Color.Red;
bttnName = txt.Name;
if (bttnName == bttnNameSpring)
{
txt.BackColor = Color.LightGreen;
}
else if (bttnName == bttnNameSummer)
{
//txt.BackColor = Color.Red;
txt.BackColor = Color.Red;
}
else if (bttnName == bttnNameAutumn)
{
txt.BackColor = Color.Yellow;
}
else if (bttnName == bttnNameWinter)
{
txt.BackColor = Color.Cyan;
}
}
catch (Exception ex)
{
MessageBox.Show("Error:\n " + ex.Message);
}
}
//Handler for mouse leaving the button
void button_MouseLeave(object sender, EventArgs e)
{
try
{
Button txt = (Button)sender;
//txt.BackColor = stkColor.Pop();
}
catch (Exception ex)
{
MessageBox.Show("Error:\n " + ex.Message);
}
}
}
}
}
Alright, so I'm just trying to create a simple program that changes the background colors of these buttons to some plain colors when you mouse over them. I had the same thing working using TextBox, but I need to get it working with button. I changed everything over to use the Button class, and it seems to have all the same functionality, but now the program runs, but nothing happens when you mouse over the buttons.
I'm pretty new to c#, stack exchange, and only slightly less so to programming in general, so sorry if I'm dinking up on etiquette/formatting my questions, etc.
I think you are trying to reference your buttons title when you are actually calling the button name
Changing:
String bttnName = null;
String bttnNameSpring = "Spring";
String bttnNameSummer = "Summer";
String bttnNameAutumn = "Autumn";
String bttnNameWinter = "Winter";
Button txt = (Button)sender;
To:
String bttnName = null;
String bttnNameSpring = "bttnSpring";
String bttnNameSummer = "bttnSummer";
String bttnNameAutumn = "bttnAutumn";
String bttnNameWinter = "bttnWinter";
Causes the code to work.
If you do infact want to use the "Spring", "Summer" etc reference than i would suggest changing
bttnName = txt.Name;
to
bttnName = txt.Text;
And ensure that the Text of the labels is set correctly

C# form instantly closing

All of a sudden my form window has begun to close as soon as the application is launched. There's nothing in the output window that gives a hint as to what could be causing it and there are no errors thrown at me either. Does anybody have any ideas?
I've provided to form's class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ProjectBoardManagement {
public partial class CreateBoard : Form {
Functions funcs = new Functions();
public CreateBoard() {
InitializeComponent();
}
private void CreateBoardButton_Click(object sender, EventArgs e) {
String BoardName = BoardNameText.Text;
String Pages = "";
String Labels = "";
foreach (ListViewItem i in PageNameList.Items) {
Pages = (Pages + i.Name.ToString() + ",");
}
foreach (ListViewItem i in LabelNameList.Items) {
Labels = (Labels + i.Name.ToString() + ",");
}
String BoardFile = ("board_" + BoardName + ".txt");
funcs.SaveSetting(BoardFile, "name", BoardName);
funcs.SaveSetting(BoardFile, "pages", Pages);
funcs.SaveSetting(BoardFile, "labels", Labels);
FormManagement.CreateBoard.Hide();
FormManagement.BoardList.LoadBoardList();
}
private void PageNameButtonAdd_Click(object sender, EventArgs e) {
String pagename = PageNameText.Text;
if (pagename != "") {
PageNameList.Items.Add(pagename);
}
PageNameText.Text = "";
}
private void LabelNameButtonAdd_Click(object sender, EventArgs e) {
String labelname = LabelNameText.Text;
if (labelname != "") {
LabelNameList.Items.Add(labelname);
}
LabelNameText.Text = "";
}
}
}
Obvious first thing to do - run it in Debug mode and stop execution on all exceptions. This should give you enough information on how to go from there.
Otherwise Functions funcs = new Functions(); looks suspicious.

OnCheckedChanged event fires more and more times for every time it is clicked

I have an ASP.NET page that contains a gridview.
I have to create columns dynamically based on a datatable, some field type info and some header texts.
I do that by creating templates.
It created the grid fine and all looks good, however when i click a checkbox and the checkedchanged event fires then something odd happens
The first time i click its fine and i get the expected values in the event
But the second time then the event gets fired with the values from the first time and then again with the values from the checkbox that i actually clicked.. The third time the event gets fired 3 times, first 2 times with the old values and the third with the correct value.
And it just keeps going like that
So im stumped!
Here is the code i hope someone can see what i am doing wrong:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace GridTest
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DoTheGridView();
}
public void CreateGrid(DataTable table, string[] types, string[] headers)
{
try
{
for (int i = 0; i < table.Columns.Count; i++)
{
TemplateField field = new TemplateField();
//header template
field.HeaderTemplate = new GridViewHandler(ListItemType.Header, table.Columns[i].ColumnName, types[i], headers[i]);
//item template
field.ItemTemplate = new GridViewHandler(ListItemType.Item, table.Columns[i].ColumnName, types[i], headers[i]);
//edit template
field.EditItemTemplate = new GridViewHandler(ListItemType.EditItem, table.Columns[i].ColumnName, types[i], headers[i]);
grid.Columns.Add(field);
}
}
catch (Exception)
{
throw;
}
}
public void DoTheGridView()
{
DataTable table = SqlHelper.GetData();
string[] types = Regex.Split("String,String,String,String,String,CheckBox", ",");
string[] headers = Regex.Split("UserID,License Key,Name,Company,Email,Xpress", ",");
CreateGrid(table, types, headers);
table.DefaultView.RowFilter = "navn like 'Anders%'";
table.DefaultView.Sort = "navn DESC";
grid.DataSource = table.DefaultView;
grid.DataBind();
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using GridTest;
public class GridViewHandler : ITemplate
{
#region data memebers
ListItemType ItemType;
string FieldName;
string InfoType;
string HeaderText;
#endregion
#region constructor
public GridViewHandler(ListItemType item_type, string field_name, string info_type, string header_text)
{
ItemType = item_type;
FieldName = field_name;
InfoType = info_type;
HeaderText = header_text;
}
#endregion
#region Methods
public void InstantiateIn(System.Web.UI.Control Container)
{
switch (ItemType)
{
case ListItemType.Header:
Literal header_ltrl = new Literal();
header_ltrl.Text = "<b>" + HeaderText + "</b>";
Container.Controls.Add(header_ltrl);
break;
case ListItemType.Item:
switch (InfoType)
{
case "CheckBox":
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
check.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
break;
case "Command":
ImageButton edit_button = new ImageButton();
edit_button.ID = "edit_button";
edit_button.ImageUrl = "~/images/edit.gif";
edit_button.CommandName = "Edit";
edit_button.Click += new ImageClickEventHandler(edit_button_Click);
edit_button.ToolTip = "Edit";
Container.Controls.Add(edit_button);
ImageButton delete_button = new ImageButton();
delete_button.ID = "delete_button";
delete_button.ImageUrl = "~/images/delete.gif";
delete_button.CommandName = "Delete";
delete_button.ToolTip = "Delete";
delete_button.OnClientClick = "return confirm('Are you sure to delete the record?')";
Container.Controls.Add(delete_button);
/* Similarly add button for insert.
* It is important to know when 'insert' button is added
* its CommandName is set to "Edit" like that of 'edit' button
* only because we want the GridView enter into Edit mode,
* and this time we also want the text boxes for corresponding fields empty*/
ImageButton insert_button = new ImageButton();
insert_button.ID = "insert_button";
insert_button.ImageUrl = "~/images/insert.bmp";
insert_button.CommandName = "Edit";
insert_button.ToolTip = "Insert";
insert_button.Click += new ImageClickEventHandler(insert_button_Click);
Container.Controls.Add(insert_button);
break;
default:
Label field_lbl = new Label();
field_lbl.ID = FieldName;
field_lbl.Text = String.Empty; //we will bind it later through 'OnDataBinding' event
field_lbl.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_lbl);
break;
}
break;
case ListItemType.EditItem:
if (InfoType == "Command")
{
ImageButton update_button = new ImageButton();
update_button.ID = "update_button";
update_button.CommandName = "Update";
update_button.ImageUrl = "~/images/update.gif";
if ((int)new Page().Session["InsertFlag"] == 1)
update_button.ToolTip = "Add";
else
update_button.ToolTip = "Update";
update_button.OnClientClick = "return confirm('Are you sure to update the record?')";
Container.Controls.Add(update_button);
ImageButton cancel_button = new ImageButton();
cancel_button.ImageUrl = "~/images/cancel.gif";
cancel_button.ID = "cancel_button";
cancel_button.CommandName = "Cancel";
cancel_button.ToolTip = "Cancel";
Container.Controls.Add(cancel_button);
}
else if (InfoType == "CheckBox")
{
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
//check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
check.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
}
else// for other 'non-command' i.e. the key and non key fields, bind textboxes with corresponding field values
{
TextBox field_txtbox = new TextBox();
field_txtbox.ID = FieldName;
field_txtbox.Text = String.Empty;
// if Inert is intended no need to bind it with text..keep them empty
if ((int)new Page().Session["InsertFlag"] == 0)
field_txtbox.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_txtbox);
}
break;
}
}
#endregion
#region Event Handlers
public void checkbox_CheckedChanged(object sender, EventArgs e)
{
CustomCheckBox cbox = (CustomCheckBox)sender;
string hej = cbox.ID.ToString();
}
//just sets the insert flag ON so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void insert_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 1;
}
//just sets the insert flag OFF so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void edit_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 0;
}
private void OnDataBinding(object sender, EventArgs e)
{
object bound_value_obj = null;
Control ctrl = (Control)sender;
IDataItemContainer data_item_container = (IDataItemContainer)ctrl.NamingContainer;
int rowid = data_item_container.DataItemIndex;
bound_value_obj = DataBinder.Eval(data_item_container.DataItem, FieldName);
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;
case ListItemType.EditItem:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
}
else
{
TextBox field_txtbox = (TextBox)sender;
field_txtbox.Text = bound_value_obj.ToString();
}
break;
}
}
#endregion
}
You might want to check that you are ensuring that you are only binding to an event once only. From first glance, it seems that you are not checking this. From your post description, it seems that this is happening.
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
If you are not sure where to bind it to ensure it only happens once, you can unbind it before the start of the function to ensure at most 1 is connected at a time:
For example:
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.CheckedChanged -= new EventHandler(checkbox_CheckedChanged);
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;
I must admit I haven't read the entire source (it's quite lengthy and malformed), but in my experience this type of behavior is caused by attaching an event handler in code that is triggered by the same event. So for the first event it would perform ok, the second time you have two event handlers, then 4 and so on.
Edit:
You can check if there already is an event handler like this:
if (cbox.CheckedChanged==null){
//bind the event handler
}

Categories