I have a class that is a list of class objects.
[Serializable]
public class UserRequestOrders
{
private List<RTORequestOrder> m_thisUsersOrders = new List<RTORequestOrder>();
public List<RTORequestOrder> RequestOrders
{
get { return m_thisUsersOrders; }
set { m_thisUsersOrders = value; }
}
}
When I create an instance of this object I need to populate the list variable When m_thisUsersOrders with an existing list of requests (from a viewstate).
MyOrders.RequestOrders = (List<RTODataEntryObjects.RTORequestOrder>)ViewState["vsMyOrders"];
When the page posts back, I cast the viewstate into a list of RTORequestOrder objects, and try to set the RequestOrders property, I get the message that the property or indexer cannot be assigned to. I have a "SET" accessor for the property.
All posts that I have read on this topic state that I need to modify scope in the application settings, but I am not sure how that applies here. I don't have any application settings set.
I am hoping someone can help me understand how I can populate the list from an existing list.
EDIT: Nico, Thanks for your response! Below is the full code from the code behind page. "MyOrders" and "lst" are essentially the same thing. When I am working with "lst" everything works the way that I want it to. The reason that I want to use the "MyOrders" object instead is because I have a method that returns the list as a datatable with only the fields I need to display. (I didnt' show that code because the issue appears to be with the "SET" accessor.) "lst" has the same signiture as the "MyOrders.RequestOrders". Why can I cast the the viewstate into the lst object, but not the MyOrders object?
EDIT: Grant, thanks for your response as well. I don't know how to set breakpoints for ASP pages... :(
public partial class Default3 : System.Web.UI.Page
{
RTODataEntryObjects.UserRequestOrders MyOrders = new RTODataEntryObjects.UserRequestOrders();
List<RTODataEntryObjects.RTORequestOrder> lst = new List<RTODataEntryObjects.RTORequestOrder>();
void Page_PreRender(object sender, EventArgs e)
{
if (ViewState["vsMyOrders"] == null)
{
NewDataGrid.DataSource = (RTODataEntryObjects.UserRequestOrders)ViewState["vsMyOrders"]; // code to show the data in the grid when page loading
}
}
protected void Page_Load(object sender, EventArgs e)
{
NewDataGrid.EnableViewState = true;
NewDataGrid.DataSource = (RTODataEntryObjects.UserRequestOrders)ViewState["vsMyOrders"];
NewDataGrid.DataBind();
}
public void btnSubmit(object sender, EventArgs e)
{
int id = Int32.Parse(TextBox1.Text); // dynamically getting the data from the frontend.
string name = TextBox2.Text; // dynamically getting the data from the frontend.
if (ViewState["vsMyOrders"] != null) // if the view state is already having data then can update the list and assign again to the viewstate later.
{
lst = (List<RTODataEntryObjects.RTORequestOrder>)ViewState["vsMyOrders"];
MyOrders.RequestOrders = (List<RTODataEntryObjects.RTORequestOrder>)ViewState["vsMyOrders"];
}
RTODataEntryObjects.RTORequestOrder thisOrder = new RTODataEntryObjects.RTORequestOrder(id, name, User.Identity.Name, System.Environment.MachineName);
lst.Add(thisOrder); //
MyOrders.AddNew(thisOrder);
ViewState["vsMyOrders"] = MyOrders;
NewDataGrid.DataSource = (IList<RTODataEntryObjects.RTORequestOrder>)ViewState["vsMyOrders"];
NewDataGrid.DataBind();
}
}
Related
EDITED! WORKING CODE
I have the following class:
class Medic
{
private readonly int codM;
private string numeM;
private string specialitate;
//i have a constructor and properties with get and set, correctly written
}
I added 3 textBoxes to the form to be filled, each one related to one of the class attributes.
After this i have a button, and if all 3 textbox fields are correctly completed, a new class object is created.
This object will be added to a List. And this list of objects I want to be displayed in a listBox, and be updated as I add new objects.
Also, I want to have 2 objects already in the List and displayed in the listBox as I run the program, created in the code I mean, not using the textBoxes, and the new entered objects to come after these. I barely know where to write the code to create these 2 objects, same as where is ok to create and populate the List of objects or to write the code to bind this list into the ListBox;
public partial class Form1 : Form
{
List<Medic> listaMedici = new List<Medic>();
Medic m1 = new Medic(0, "ion", "endocrinologie");
public Form1()
{
InitializeComponent();
listaMedici.Add(m1);
}
private void button1_AddObject_Click(object sender, EventArgs e)
{
if (textBox1_cod.Text == "")
errorProvider1.SetError(textBox1_cod, "Introduceti codul medicului!");
else if (textBox2_nume.Text == "")
errorProvider1.SetError(textBox2_nume, "Introduceti numele medicului");
else if (Regex.IsMatch(textBox2_nume.Text, #"^[ a-zA-Z]+$") == false)
errorProvider1.SetError(textBox2_nume, "Numele contine doar litere si spatii");
else if (textBox3_specialitate.Text == "")
errorProvider1.SetError(textBox3_specialitate, "Introduceti specialitatea medicului");
else
{
try
{
Medic medic = new Medic(Convert.ToInt32(textBox1_cod.Text), textBox2_nume.Text, textBox3_specialitate.Text);
foreach (Medic m in listaMedici)
{
if (textBox1_cod.Text == m.CodM.ToString())
{
throw new Exception("Codul contractului incalca proprietatea de unicitate. Introduceti un cod unic");
textBox1_cod.Clear();
}
}
listaMedici.Add(medic);
listBox1_medici.DataSource = new ObservableCollection<Medic>(listaMedici);
listBox1_medici.DisplayMember = nameof(Medic.NumeM);
listBox1_medici.ValueMember = nameof(Medic.CodM);
listBox1_medici.SelectedIndex = 0;
MessageBox.Show("ADDED!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
errorProvider1.Clear();
textBox1_cod.Clear();
textBox2_nume.Clear();
textBox3_specialitate.Clear();
}
}
}
private void listBox1_medici_SelectedIndexChanged(object sender, EventArgs e)
{
}
The display member should be the name of the property to display, not a string property. Reflection is used to look for a property of the name of the display member. For example if your medic.NumeM value is "Hello" WPF will look for a property named "Hello", retrieve the value of the property and display it in the listbox.
In your case the code should be: listBox1_medici.DisplayMember = "NumeM";
I am a not experienced programmer, just a rookie enthusiast.
I have a webForm where I add items to a drop-down list.
There is another webform that contains another drop-down list, I want this second "ddl" to display the items I added to the "first ddl".
After not succeeding with public properties, I tried to get this accomplished in the most straight fashion:
In designer.cs change the first "ddl" from protected global to public.
On the second webForm I wrote:
WebForm3 wf_ConfigurationPage = new WebForm3();
And a short function with these lines:
ddl_ingenieros.DataSource = wf_ConfigurationPage.ddl_Engineers;
ddl_ingenieros.DataBind();
I am calling the function from PageLoad but unfortunately the "ddl" is not showing the items from its "DataSource ddl".
Also, when I switch pages, the items I added to the original "ddl" just disappear.
Can you help me get these 2 issues resolved?
I managed to get something similiar done for a gridview as follows:
On the webform where the original gridview is located:
static DataSet DS;
static DataTable tableRequests;
/* -------------- Public Properties ---------------- */
public DataSet currentList //Allows access from other pages.
{
get {
return DS;
}
}
public DataTable currentTable {
get {
return tableRequests;
}
}
On the second webForm I wanted to show the gridview:
WebForm1 wf_ActiveReq = new WebForm1();
Then a short function that I call from PageLoad, which has these lines:
gv_results.DataSource = wf_ActiveReq.currentList;
gv_results.DataBind();
I was unable to do the same with the ddls because unlike the DataSet and the Data Table, the ddl was created from designer view, when I tried to declared them in the "code behind" of the webForm where the "original" ddl exists I got an error about the object being duplicate, which makes sense.
Thanks for your time
#Erkaner
In first webForm:
static List<string> myItems = new List<string>();
protected void btn_add_Click(object sender, EventArgs e)
{
if (Session["myItems"] != null)
{
myItems = (List<string>) Session["myItems"];
}
myItems.Add(txt_newAdmin.Text);
ddl_Engineers.DataSource = myItems;
ddl_Engineers.DataBind();
txt_newAdmin.Text = "";
}
In second webForm, I wrote a function I call from pageLoad:
private void pull_engineersList()
{
ddl_ingenieros.DataSource = Session["myItems"];
ddl_ingenieros.DataBind();
}
Thanks again!
Why not use Session :
In the first page:
Session["myddlstore"] = myFirstDDL.DataSource;
and in the second page
mySecondDDL.DataSource = Session["myddlstore"];
mySecondDDL.DataBind();
UPDATE
If the dropdowlinst items are added by the user, then you can implement something like this in the button click that adds item to the dropdownlist:
List<string> myitems = new List<string> ();
if(Session["myitems"] != null)
{
myitems = (List<string>) Session["myitems"];
}
myitems.Add(txt_NewItem.Text);
myFirstDDL.DataSource = myitems;
myFirstDDL.DataBind();
and, similarly. in the second page
mySecondDDL.DataSource = Session["myitems"];
mySecondDDL.DataBind();
Session["myitems"] = myitems;
If you store a more complex object in dropdownlist, I would define a class that represents the complex object, and still use the approach described above (List<ObjectType>).
I have a form that I would like to reuse for both adding a new record and editing an existing record. I am able to successfully load the page with the relevant data when I select a record from a GridView and I am able to update the db record appropriately. However, my issue is trying to use the form for both executions. Here is my logic in code behind: (I assign a session variable when I click on the row in GridView and this does work successfully)
protected void Page_Load(object sender, EventArgs e)
{
resultOutput.Visible = false;//Output results as to whether or not a record was added successfully is automatically hidden at page load
//Checking to see if session variable has been created
if (Session["editID"] != null)
{
//Create objects to get recipe data
dbCRUD db = new dbCRUD();
Recipe editRecipe = new Recipe();
//Grabbing session ID and assigning to a variable in order to remove the session variable
var id = Convert.ToInt32(Session["editID"]);
Session.Remove("editID");
//Call method to retrieve db data
editRecipe = db.SelectRecord(id);
//Populate results to text boxes
recordID.Text = id.ToString();
addName.Text = editRecipe.Name;
addTypeDDL.SelectedValue = editRecipe.Meal;
addDifficultyDDL.SelectedValue = editRecipe.Difficulty;
addCookTime.Text = editRecipe.Cook_Time.ToString();
addDirections.Text = editRecipe.Directions;
//Change Button Text
submitRecord.Visible = false;
changeRecord.Visible = true;
//Change Title Text
addEditTitle.Text = "Edit Recipe";
}
}
protected void submitRecord_Click(object sender, EventArgs e)
{
//Variables for execution results
var modified = "";
int returned = 0;
//Creating the recipe Object to pull the values from the form and
//send the recipe object as a parameter to the method containing insert stored procedure
//depending on Add or Edit
Recipe recipe = new Recipe();
recipe.Name = addName.Text;
recipe.Meal = addTypeDDL.Text;
recipe.Difficulty = addDifficultyDDL.Text;
recipe.Cook_Time = int.Parse(addCookTime.Text);
recipe.Directions = addDirections.Text;
//Creating object to access insert method
dbCRUD newRecord = new dbCRUD();
//Checking to see if the page is loaded for edit or new addition
if (Session["editID"] != null)
{
//If recordID exists, recipe will be passed as to UpdateRecord method
recipe.Recipe_ID = int.Parse(recordID.Text);
returned = newRecord.UpdateRecord(recipe);
modified = "has been edited.";
Session.Remove("editID");
}
else
{
//If recordID does not exist, record will be passed to InsertRecord method (new recipe)
returned = newRecord.InsertRecord(recipe);
modified = "added";
}
//Method returns 0 if successful, 1 if sql error, 2 if other error
if (returned == 1)
{
resultOutput.Text = "There was an sql exception";
resultOutput.Visible = true;
}
else if (returned == 2)
{
resultOutput.Text = "There was a non sql exception";
resultOutput.Visible = true;
}
else
{
resultOutput.Text = "\"" + addName.Text + "\" recipe " + modified;
resultOutput.Visible = true;
}
}
I have issues on the if(Session["editID"] != null) line - I am always moved to the else logic and the if logic never runs.
Here is my click method in the GridView:
protected void Grid_Recipe_SelectedIndexChanged(object sender, EventArgs e)
{
int index = Convert.ToInt32(Grid_Recipe.SelectedDataKey.Value);
Session["editID"] = index;
Response.Redirect("addRecord.aspx");
}
My question is how can I control execution during the submitRecord_Click event so that I call the appropriate method. Thanks!
Have you considered using
if(Page.IsPostBack)
{
code here
}
To detect whether you are posting back to the page? Then you could check your value of the item. I see no reason the code shouldn't be in the Session variable - have you tried putting a breakpoint in there to see if the code actually gets in there?
Also does your addRecord.aspx just add the record? If so, just add the record in this class, but use the PostBack check to see. Could you just make sure you are saving in the right context aswell:
// Outside of Web Forms page class, use HttpContext.Current.
HttpContext context = HttpContext.Current;
context.Session["editID"] = index;
...
int Id = (string)(context.Session["editID"]);
I was able to figure out my issue - which actually turned into two issues. First, I had to put my Page Load logic in a if(!IsPostBack) statement because I could not edit the page. Reason being is I was loading the originally posted data to the form on page load, which executed before my logic. Adding the if(!IsPostBack) control statement fixed this issue. From there, I'm still using a session variable to control code behind logic, only I made sure keep my session variable only between the form and the gridview. Basically, when the gridview loads and it is not a post back, the session variable is cleared. This let's me set a new session variable when I click on a row and then the session variable is cleared once I return to the grid to see the results. Thanks for the help!
I am trying to load session data in grid but no data is loaded my code is
protected void imageAddExtraField_Click(object sender, ImageClickEventArgs e)
{
List<ContentInfo> lstExtraFields = new List<ContentInfo>();
if (Session["ExtraField"] != null)
{
lstExtraFields = Session["ExtraField"] as List<ContentInfo>;
}
else
{
ContentInfo obj = new ContentInfo();
obj.ExtraFieldValue = ckEditorExtraField.Text;
obj.ExtraField = ddlExtraField.SelectedItem.ToString();
lstExtraFields.Add(obj);
gdvExtraField.DataSource = lstExtraFields;
gdvExtraField.DataBind();
Session["ExtraField"] = lstExtraFields;
}
}
i am using VS2008 any solution thanks.
I'm not sure if this is your intention, but when is something in the Session["ExtraFiled"], imageAddExtraField_Click does nothing with it. If you want to add more objects you might need to refactor a bit the code:
protected void imageAddExtraField_Click(object sender, ImageClickEventArgs e)
{
// check if nothing in the session, on success create a new list
if (Session["ExtraField"] == null)
{
Session["ExtraField"] = new List<ContentInfo>();
}
// get a reference to the list in session; previous code ensures is something
List<ContentInfo> lstExtraFields = (List<ContentInfo>)Session["ExtraField"];
ContentInfo obj = new ContentInfo();
obj.ExtraFieldValue = ckEditorExtraField.Text;
obj.ExtraField = ddlExtraField.SelectedItem.ToString();
lstExtraFields.Add(obj);
// bind the grid
gdvExtraField.DataSource = lstExtraFields;
gdvExtraField.DataBind();
// how do you bind when !PostBack?
}
}
Make sure the ExtraField is List object. 2. make sure the gridview is programmed to display the data (automatic column generation or manual column generation).
I've been using this programming style, that I've seen in an example and just started using it, because it does the job... I would like to know other programmers' opinion about it...
So the situation is when you have a GridView, or a control based on it like the RadGrid, and you want to keep track of a data table while you are adding, editing, reordering and deleting rows.
Using the session to hold the data table (or list of data) may not be the best solution, because the user may open two identical web pages… Using the ViewState to hold the data may be and option... I have been using an approach like the following:
public partial class DefaultPage : System.Web.UI.Page
{
protected DataLine DefaultDataLine()
{
DataLine dl = new DataLine();
dl = new DataLine();
dl.Number = 0;
dl.Title = "";
dl.Text = "";
return dl;
}
protected class DataLine
{
public int Number { get; set; }
public string Title { get; set; }
public string Text { get; set; }
}
protected static List<DataLine> tempLines;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
tempLines = RadGridBindStartUpData();
}
}
protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
RadGrid1.DataSource = tempLines;
}
protected void RadGrid1_InsertCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
List<DataLine> table = tempLines;
DataLine newRow = new DataLine ();
RadTextBox rtb;
rtb = (RadTextBox)editedItem.FindControl("RadTextBoxTitle");
newRow.Title = rtb.Text;
rtb = (RadTextBox)editedItem.FindControl("RadTextBoxDescription");
newRow.Description = rtb.Text;
RadNumericTextBox number = (RadNumericTextBox)editedItem.FindControl("RadNumericTextBoxNumber");
newRow.Number = number.Value.HasValue ? Convert.ToInt32(number.Value.Value) : 0;
table.Add(newRow);
}
// ...
So using a static List variable, of a custom object (class), declared in the code-behind of the Aspx page, and updating it whenever the data is edited.
What are your thoughts about this approach? Is it okay? How do you hold your table-format data for edition (prior to saving it in the database)?
Not exactly sure what you're going for, but using a static variable is probably not what you want to do. Static properties are shared across all user/threads, so all concurrent users would be editing the same data.
If you are just looking to persist a small data set across post-backs to the same page, use the ViewState instead. Just be mindful of potential performance issues if you plan on cramming lots of data into it.
It depends on what you're wanting to achieve
Viewstate will keep the data on that page - it won't be available on any other pages (or tabs, or windows)
Session will keep the data on the server, this means it will be available for any page the user is looking at (on your site) and it will keep it until the session times out.
Theres a lot of advtanges/disadvantages to either method, therefore you need to research your situation, here is a start.
You mentioned storing in the session, and how this could cause issues if the user opens up multiple copies of the page, etc...
We had a similar issue so I made a property in code behind on the page and on first page load (if not postback blah blah) I generate a new guid. Then I use the guid value as my session key and I know it'll be unique per page.
You could make a spify property like this...
Public ReadOnly Property SessionDataKey() As String
Get
If ViewState("SessionDataKey") Is Nothing Then
ViewState("SessionDataKey") = Guid.NewGuid()
End If
Return ViewState("SessionDataKey").ToString()
End Get
End Property
But in short, I just use the session.
Thank you very much for your replies! With your help, and some research, I see that both approaches, storing in session or using the static variable are indeed wrong, at least for the purpose I was using them... All your answers were helpful, and although I can only mark one as correct, I would like to leave my appreciation.
Well, for anyone stumbling across the same problem, here’s what I’ve implemented in my pages:
public partial class ScriptAdd : System.Web.UI.Page
{
private List<MyItem> tempMyItems
{
get
{
//if (ViewState["tempMyItemsList"] == null)
// ViewState["tempMyItemsList"] = new List<MyItem>();
return (List<MyItem>)ViewState["tempMyItemsList"];
}
set
{
ViewState.Add("tempMyItemsList", value);
}
}
protected void Page_Load(object sender, EventArgs e)
{
// ...
}
}
And then use it whenever I want to add / insert / update lines to my temporary list:
List<MyItem> table = tempMyItems;
table.RemoveAt(idx);
MyItem newRow = new MyItem ();
// ...
table.Insert(idx, newRow);
Finally, if intended, I store all the items in the database.