Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi all! We have been experiencing an issue on site where threads have been missing the latest postings. The platform host Vanilla are working on this issue. A workaround that has been used by some is to navigate back from 1 to 10+ pages to re-sync the thread and this will then show the latest posts. Thanks, Mike.
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

C# shopping basket, trying to remove an item...

2456

Comments

  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Darragh29 wrote: »
    On that blog I mentioned above for the Dynamic Controls, there was a lot of talk about something you've mentioned above, the ascx page... According to his blog, I just need to create the control for the Linkbutton I need in an ascx page (I think), and then it is added to the control tree or recreated programatically on postback... I'm just afraid that all I need, over and above what I've done to date, is one or two lines of code to get this over the fence... What I have works perfectly except for the last little bit! :confused::confused::confused:

    ASCX files are UserControls..

    Similar to the way that you use a text box or datagrid they are just controls you can make yourself

    Using my code samples above

    My FEControl is just 2 textboxes in a table organised in 2 rows

    In your case you can think of it as this.. what do I need to show in a single row and design it as such.

    Create an ASCX file by just adding a new user control to your project.

    Design the HTML/ Server controls the exact same was as an ASPX page (just leave out html/body tags)

    In your code behind, add a method like such
    private Expert _data;
    
     public override void DataBind()
            {
                if (Data != null)
                {
                     //assign textbox.text = Data.YourPropertyName
                    _data = null;
                }
    
                base.DataBind();
            }
    
    
      public Expert Data
            {
                get
                {
    
     if (_data == null)
                    {
                        _data = textBox.text //your stuff here
                    }
                    return _data;
                                }
                set { _data=value; }
            }
    

    My object Expert is a class which contains string properties, called name and number

    This will allow your control to be passed the object it expects and put all the values in the correct place...

    Now!

    You need one last thing, someway to say Delete ME!!!!!

    Add a linkbutton (you have them :D) and then add the following
    protected void RemoveItem(object sender, EventArgs args)
            {
                RaiseBubbleEvent(this, new CommandEventArgs("Remove", null));
            }
    
    

    My linkbutton onClick event is RemoveItem

    The RaiseBubbleEvent sends an event notice to the repeater which knows that when it recieves an event it uses the ItemCommand handler that you added before (see the previous post)

    You check to see is the event name called Remove and if it is, you can get the value of its index and remove it.


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    You see here's my problem, I've gotten to this point with a lot of help and some luck! I don't really fully understand how methods, functions, arguments and all that stuff works! It's taken me weeks of struggling and burning midnight oil just to get to where I have it at the moment, so if I've to go back and change the approach, I know I'll be into weeks of messing and trial by error because I don't really fully understand C# well enough or asp.net to just ditch one approach and pick up another one. I hope you see where I'm coming from with this, if I was a bit more fluent with it I'd probably give it a go but if I have to spend another 2 weeks at this the pc will be fired through the window and out onto the street!

    Do you think it would be possible can use an ascx user control to get over this headwrecker problem I'm having with my Linkbutton??? I'm so frustrated with it because it looks perfect, and must be close to working based on where I have it at the moment.

    If the Linkbutton has to be created in the Page_Load function, could I not just create the LinkButton there and call it somewhere else in my code???

    Or put my LinkButton code into the ascx file and call it up when I need it in my code???


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    I hear ya, I hear ya...

    The LinkButton is place in the ASCX file..

    Problem for you is this,

    By the time you assign your linkbutton handler in code it is too late in page cycle to work for it, hence why it worked in page load...

    You could put the whole thing in the page load and check if you are getting a command back so that it will work but its messy

    Something like

    If(Page.IsPostBack && Request.Form["fo"] == true)
    {
    Do whatever you did in the other function
    }


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    I've come up with a sort of a sh*ty solution but it's kind of getting me moving in the right direction again! Here goes...

    Just in relation to the LinkButton event, I've moved this into the Page_Load function but I've also created a new DB connection for the Linkbutton with a new while loop that kind of (but doesn't exactly yet!) replicates the behaviour of the LinkButton when it was in the Button1_Click function...

    So now my Page_Load which was empty except for the sessionID code, looks like this...

    public void Page_Load(object sender, EventArgs e)
    {
    if (this.Session["dummy"] == null) { this.Session["dummy"] = 1; } lblSessionID.Text = this.Session.SessionID;

    SqlConnection connUS = new SqlConnection("Data Source=My working connection string");
    connUS.Open();

    string selectSQLUS;

    selectSQLUS = "SELECT * FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";
    SqlCommand cmdUS = new SqlCommand(selectSQLUS, connUS);
    cmdUS.CommandType = CommandType.Text;

    SqlDataReader DataReader;
    DataReader = cmdUS.ExecuteReader();

    if (DataReader.HasRows)
    {
    //Label13.Text = "";

    while (DataReader.Read())
    {

    LinkButton Delete_Btn = new LinkButton();
    Delete_Btn.ID = string.Format(DataReader["Project_ID"].ToString());
    Delete_Btn.Text = "Remove Item<BR><BR>";
    Delete_Btn.CommandName = "DeleteMe";
    Delete_Btn.PostBackUrl = "~/MainTestX.aspx";
    Delete_Btn.Click += new EventHandler(Delete_Btn_Click);
    Delete_Btn.CommandArgument = ("12");
    Panel1.Controls.Add(Delete_Btn);
    }
    }
    }


    It needs to be tidyed up a bit but it's a fraction closer to where I was up until now with it.


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    You see here's my problem, I've gotten to this point with a lot of help and some luck! I don't really fully understand how methods, functions, arguments and all that stuff works! It's taken me weeks of struggling and burning midnight oil just to get to where I have it at the moment, so if I've to go back and change the approach, I know I'll be into weeks of messing and trial by error because I don't really fully understand C# well enough or asp.net to just ditch one approach and pick up another one. I hope you see where I'm coming from with this, if I was a bit more fluent with it I'd probably give it a go but if I have to spend another 2 weeks at this the pc will be fired through the window and out onto the street!

    Do you think it would be possible can use an ascx user control to get over this headwrecker problem I'm having with my Linkbutton??? I'm so frustrated with it because it looks perfect, and must be close to working based on where I have it at the moment.

    If the Linkbutton has to be created in the Page_Load function, could I not just create the LinkButton there and call it somewhere else in my code???

    Or put my LinkButton code into the ascx file and call it up when I need it in my code???

    You'll have to overcome the Page Life cycle hurdle using both approaches because they work the same way I'm afraid :o

    I had been programming in my spare time for about a year until I needed to code some functionality that required dynamically created controls, you on the other hand, are jumping straight in!

    To work with dynamically created controls, you need to understand the different stages that a page must go through before it's rendered as a html document to the client browser. It's absolutely essential that you know when events are hooked up, when controls should be added, viewstate is loaded or saved etc etc.

    I'd advise you to stick with it a little longer. When you do grasp it everything will click for you, and you'll be able to enjoy the benefits of reusable controls. There's no shortage of information about the Life cycle on google, so take a break from this project and find a tutorial which guides you through demonstrating what it is and how it works. Its impossible for us to explain it to you on here without writing our own article on it ;)


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    I've come up with a sort of a sh*ty solution but it's kind of getting me moving in the right direction again! Here goes...

    Just in relation to the LinkButton event, I've moved this into the Page_Load function but I've also created a new DB connection for the Linkbutton with a new while loop that kind of (but doesn't exactly yet!) replicates the behaviour of the LinkButton when it was in the Button1_Click function...

    So now my Page_Load which was empty except for the sessionID code, looks like this...

    public void Page_Load(object sender, EventArgs e)
    {
    if (this.Session["dummy"] == null) { this.Session["dummy"] = 1; } lblSessionID.Text = this.Session.SessionID;

    SqlConnection connUS = new SqlConnection("Data Source=My working connection string");
    connUS.Open();

    string selectSQLUS;

    selectSQLUS = "SELECT * FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";
    SqlCommand cmdUS = new SqlCommand(selectSQLUS, connUS);
    cmdUS.CommandType = CommandType.Text;

    SqlDataReader DataReader;
    DataReader = cmdUS.ExecuteReader();

    if (DataReader.HasRows)
    {
    //Label13.Text = "";

    while (DataReader.Read())
    {

    LinkButton Delete_Btn = new LinkButton();
    Delete_Btn.ID = string.Format(DataReader["Project_ID"].ToString());
    Delete_Btn.Text = "Remove Item<BR><BR>";
    Delete_Btn.CommandName = "DeleteMe";
    Delete_Btn.PostBackUrl = "~/MainTestX.aspx";
    Delete_Btn.Click += new EventHandler(Delete_Btn_Click);
    Delete_Btn.CommandArgument = ("12");
    Panel1.Controls.Add(Delete_Btn);
    }
    }
    }


    It needs to be tidyed up a bit but it's a fraction closer to where I was up until now with it.

    That looks alright, is it working for you?

    Can you get Delete_Btn_Click to fire?


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    John_Mc wrote: »
    That looks alright, is it working for you?

    Can you get Delete_Btn_Click to fire?

    Hi John,

    It's firing now but the overall shopping cart isn't working as it should. It's basically out of sync with the actual contents of the cart (as per the items being posted into the DB after a Button1_Click event is triggered) but I think this is due to the fact that when I fire the Button1_Click event, the page doesn't actually re-load again so what is going on in the Page_Load event doesn't get executed. I'm a little hazy on what is happening at the moment but I'll try to break it down bit by bit and see if I can understand what is happening and when.


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Just wondering is there a way I can put a line of code into a function that forces the page to refresh or to run the Page_Load function again???


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    Just wondering is there a way I can put a line of code into a function that forces the page to refresh or to run the Page_Load function again???

    Put the code that loads the cart into a function and call it from Page_Load and whenever the content of the cart is modified.

    private void LoadCart()
    {

    }


  • Advertisement
  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    John_Mc wrote: »
    Put the code that loads the cart into a function and call it from Page_Load and whenever the content of the cart is modified.

    private void LoadCart()
    {

    }

    But how do I "call it"??? I know these are basic questions, thanks for being patient with me on this! The way I survived this in uni was just horse everything into one function and somehow I managed to get away with it, so I never had to worry about working with different functions or arguments or methods or anything like that!


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    But how do I "call it"???

    LoadCart();


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    John_Mc wrote: »
    Put the code that loads the cart into a function and call it from Page_Load and whenever the content of the cart is modified.

    private void LoadCart()
    {

    }

    Is it possible to do something like this:

    PageLoad()

    {
    LoadCart();
    DeleteItem();

    Panel1.Controls.Add(LoadCart(Product_Label));
    Panel1.Controls.Add(DeleteItem(Delete_LinkBtn));
    }


    If I wanted to bring together two separate controls from two different functions into my panel in the Page_Load function??? Assuming that I had one function called LoadCart to add items to my cart and another one called DeleteItem to delete an item??? I've tried it and am getting an error saying:

    The name 'LoadCart_Product_Label' does not exist in the current context


    What I mean is if I call up a function, are the controls that are within that function I'm calling up, not brought in within the scope of the function I'm calling this function from???


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    Is it possible to do something like this:

    PageLoad()

    {
    LoadCart();
    DeleteItem();

    Panel1.Controls.Add(LoadCart(Product_Label));
    Panel1.Controls.Add(DeleteItem(Delete_LinkBtn));
    }


    If I wanted to bring together two separate controls from two different functions into my panel in the Page_Load function??? Assuming that I had one function called LoadCart to add items to my cart and another one called DeleteItem to delete an item??? I've tried it and am getting an error saying:

    The name 'LoadCart_Product_Label' does not exist in the current context


    What I mean is if I call up a function, are the controls that are within that function I'm calling up, not brought in within the scope of the function I'm calling this function from???

    I assume LoadCart_Product_Label is a control created and used within LoadCart() or LoadDelete()?

    If that's the case then only LoadCart or LoadDelete will know what it is and only it can add it to the container.

    There's no reason why you should add the controls created by your functions outside of those functions.


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Well I've gone full circle with it now, I've managed to get the Delete_Btn Linkbutton working with the event handler, but now I have too many iterations of my LinkButton! ARGH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    Well I've gone full circle with it now, I've managed to get the Delete_Btn Linkbutton working with the event handler, but now I have too many iterations of my LinkButton! ARGH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    What do you mean? Is it being called twice or are there duplicate items in the cart?

    If it's the latter then clear the container of any controls before starting to add them.

    If its the former use the IsPostback property prevent calling the LoadCart method in Page load.

    E.g
    if(!IsPostback)
    {
    LoadCart();
    }
    


  • Advertisement
  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    John_Mc wrote: »
    What do you mean? Is it being called twice or are there duplicate items in the cart?

    If it's the latter then clear the container of any controls before starting to add them.

    If its the former use the IsPostback property prevent calling the LoadCart method in Page load.

    E.g
    if(!IsPostback)
    {
    LoadCart();
    }
    

    It's hard to explain what the problem is... I've tried clearing the container of controls but no matter what way I try to do it, I can't seem to get the solution I want...

    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.Web.Services;
    using System.Collections.Specialized;
    using AjaxControlToolkit;
    using System.Data.SqlClient;
    using System.Data.OleDb;
    using System.Web.SessionState;
    using System.Text;

    public partial class _Default : System.Web.UI.Page
    {
    private bool CreateControls
    {
    get
    {
    return ViewState["CreateControls"] != null ? (bool)ViewState["CreateControls"] : false;
    }
    set
    {
    ViewState["CreateControls"] = value;
    }
    }


    protected void Page_Load(object sender, EventArgs e)
    {
    if (this.Session["dummy"] == null) { this.Session["dummy"] = 1; } lblSessionID.Text = this.Session.SessionID;

    if (CreateControls)
    {
    CreateTheControls();
    }
    }


    protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
    {
    // Get selected values
    string make = DropDownList1.SelectedItem.Text;
    string model = DropDownList2.SelectedItem.Text;
    string color = DropDownList3.SelectedItem.Text;

    // Output result string based on which values are specified
    if (string.IsNullOrEmpty(make))
    {
    Label1.Text = "Please Select an Engine Type.";
    }
    else if (string.IsNullOrEmpty(model))
    {
    Label1.Text = "Please select a model.";
    }
    else if (string.IsNullOrEmpty(color))
    {
    Label1.Text = "Please Select a Make.";
    }
    else
    {
    string dropdowna = DropDownList1.SelectedValue;
    string dropdownb = DropDownList2.SelectedValue;
    string dropdownc = DropDownList3.SelectedValue;


    DateTime myDateTime1 = new DateTime();
    myDateTime1 = new DateTime();
    myDateTime1 = DateTime.Now;

    string selectSQL;

    //Connection for SELECT FROM "Vehicle data"
    SqlConnection connz = new SqlConnection("Data Source....");
    connz.Open();

    selectSQL = "SELECT * FROM Vehicle_Data WHERE Vehicle_Make = '" + DropDownList1.SelectedItem.Value + "' AND Vehicle_Model = '" + DropDownList2.SelectedItem.Value + "' AND Engine_Type = '" + DropDownList3.SelectedItem.Value + "'";

    SqlCommand cmdy = new SqlCommand(selectSQL, connz);
    cmdy.CommandType = CommandType.Text;

    SqlDataReader myDataReader;
    myDataReader = cmdy.ExecuteReader();

    Label1.Text = string.Format("Vehicle Information: {0} {1}.", make, model);
    Label7.Text = string.Format("Engine Type: {0}.", color);

    while (myDataReader.Read())

    {
    Label2.Text = string.Format("Your Purchase ID is: {0} ", myDataReader["Stock_Code"]);
    Label12.Text = string.Format("Retail Price: €");
    Label14.Text = string.Format("Product Info: ");
    Label3.Text = string.Format("{0:F2}", myDataReader["Retail_Price"]);
    Label4.Text = string.Format("{0} ", myDataReader["Product_Description"]);
    Label5.Text = string.Format("{0} ", myDataReader["Component_Manufacturer"]);
    Label15.Text = string.Format("Manufacturer: ");
    Label6.Text = string.Format("Timestamp: {0} ", myDateTime1);

    }

    myDataReader.Close();
    connz.Close();
    }
    }

    [WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public static CascadingDropDownNameValue[] GetDropDownContentsPageMethod(string knownCategoryValues, string category)
    {
    return new CarsService().GetDropDownContents(knownCategoryValues, category);
    }

    public void Button1_Click(object sender, EventArgs e)
    {
    SqlConnection conn = new SqlConnection("Data Source....");
    conn.Open();

    if (this.Session["dummy"] == null) { this.Session["dummy"] = 1; } lblSessionID.Text = this.Session.SessionID;


    string TransDateTime = DateTime.UtcNow.ToString("r");

    string Delivery = string.Format("7.50");
    string dropdown1 = DropDownList1.SelectedValue;
    string dropdown2 = DropDownList2.SelectedValue;
    string dropdown3 = DropDownList3.SelectedValue;
    string Manufacturer = Label5.Text;
    string Description = Label4.Text;
    string Retail = Label3.Text;
    string SessionID = lblSessionID.Text;


    string sql = "insert into used_equipment (eq_type, eq_make, eq_model, SessionID, Retail_Price, Component_Manufacturer, Product_Description, Date_Time, Delivery_Cost)\n";
    sql += "values(";

    sql += "'" + dropdown1 + "',";
    sql += "'" + dropdown2 + "',";
    sql += "'" + dropdown3 + "',";
    sql += "'" + SessionID + "',";
    sql += "'" + Retail + "',";
    sql += "'" + Manufacturer + "',";
    sql += "'" + Description + "',";
    sql += "'" + TransDateTime + "',";
    sql += "'" + Delivery + "')";

    SqlCommand cmd = new SqlCommand(sql, conn);
    cmd.CommandType = CommandType.Text;
    cmd.ExecuteNonQuery();
    conn.Close();


    ////////////////////////////////////////////////////////////////

    string selectSQLX;
    string selectSUM;
    string SumDelivery;

    SqlConnection connT = new SqlConnection("Data Source....");
    connT.Open();

    SqlConnection connP = new SqlConnection("Data Source....");
    connP.Open();

    SqlConnection connX = new SqlConnection("Data Source....");
    connX.Open();

    selectSQLX = "SELECT * FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";
    selectSUM = "SELECT SUM(Retail_Price) FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";
    SumDelivery = "SELECT SUM(Delivery_Cost) FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";

    SqlCommand cmdy = new SqlCommand(selectSQLX, connT);
    cmdy.CommandType = CommandType.Text;

    SqlCommand cmdu = new SqlCommand(selectSUM, connP);

    SqlCommand cmdL = new SqlCommand(SumDelivery, connX);


    SqlDataReader DataReader;
    DataReader = cmdy.ExecuteReader();

    Panel1.Controls.Clear();
    if (DataReader.HasRows)
    {
    //Label13.Text = "";

    while (DataReader.Read())
    {

    object obj1 = new object();
    obj1 = string.Format(DataReader["eq_type"].ToString());

    object obj2 = new object();
    obj2 = string.Format(DataReader["eq_make"].ToString());

    object obj3 = new object();
    obj3 = string.Format(DataReader["eq_model"].ToString());

    object obj4 = new object();
    obj4 = string.Format(DataReader["Component_Manufacturer"].ToString());

    object obj5 = new object();
    obj5 = string.Format(DataReader["Product_Description"].ToString());

    object obj6 = new object();
    obj6 = string.Format(DataReader["Retail_Price"].ToString());

    object obj7 = new object();
    obj7 = string.Format(DataReader["Project_id"].ToString());

    string newstring = string.Concat(obj1, " " + obj2, " " + obj3, "<br>" + obj4, " " + obj5, "<br>Retail Price: € " + obj6, "<BR>" + obj7, "<BR>");

    Label Product_Label = new Label();
    Product_Label.ID = string.Format(DataReader["Project_id"].ToString());
    Product_Label.Text = newstring.ToString();


    Panel1.Controls.Add(Product_Label);

    CreateControls = true;
    CreateTheControls();


    }



    decimal Cart = Convert.ToDecimal(cmdu.ExecuteScalar());
    decimal Carry = Convert.ToDecimal(Delivery);
    decimal Cart_Total = Cart + Carry;

    Label Shopping_Cart = new Label();
    Shopping_Cart.ID = "Cart";
    Shopping_Cart.Text = string.Format("Order Total: € {0} ", (Cart));

    Label Shipping_Label = new Label();
    Shipping_Label.ID = "Shipping";
    Shipping_Label.Text = string.Format("<BR>Shipping: € {0} ", (Carry));

    Label Order_Total = new Label();
    Order_Total.ID = "Order_Tot";
    Order_Total.Text = string.Format("<BR>Invoice Total: € {0} ", (Cart_Total));

    Panel1.Controls.Add(Shopping_Cart);
    Panel1.Controls.Add(Shipping_Label);
    Panel1.Controls.Add(Order_Total);

    }

    DataReader.Close();
    connT.Close();
    connP.Close();
    }


    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {

    }

    protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
    {

    }

    protected void Button2_Click(object sender, EventArgs e)
    {

    }

    protected void Delete_Btn_Click(object sender, EventArgs e)
    {
    Label Delete_Text = new Label();
    Delete_Text.ID = string.Format("12");
    Delete_Text.Text = string.Format("Item has been deleted!");
    Panel1.Controls.Clear();
    Panel1.Controls.Add(Delete_Text);

    }

    public void CreateTheControls()
    {

    SqlConnection connUS = new SqlConnection("Data Source....");
    connUS.Open();

    string selectSQLXUS;

    selectSQLXUS = "SELECT * FROM used_equipment WHERE SessionID = '" + this.Session.SessionID + "'";

    SqlCommand cmdUS = new SqlCommand(selectSQLXUS, connUS);
    cmdUS.CommandType = CommandType.Text;
    SqlDataReader MyDataReader;
    MyDataReader = cmdUS.ExecuteReader();

    if (MyDataReader.HasRows)
    {
    ////////////////////////////////////////////////////////////

    while (MyDataReader.Read())
    {

    LinkButton Delete_Btn = new LinkButton();
    Delete_Btn.ID = string.Format(MyDataReader["Project_id"].ToString());
    Delete_Btn.Text = "Remove Item<BR><BR>";
    Delete_Btn.CommandName = "DeleteMe";
    //Delete_Btn.PostBackUrl = "~/MainTestX.aspx";
    Delete_Btn.OnClientClick = "";
    Delete_Btn.CommandArgument = string.Format("13");
    Delete_Btn.Click += new EventHandler(Delete_Btn_Click);
    Panel1.Controls.Add(Delete_Btn);

    }
    }

    }

    }

    The code in bold seems to be the problem. If I add in a clear container where I've inserted the comment line in bold, I end up clearing out the whole container, including the grey text that is my Product_Label string.

    You can see the problem more clearly in the attached image... The linkButton ID's for both buttons are $479 and $480 when I hover the mouse over them...

    I had this problem before with a label and I resolved it by appending two pieces of into into the one label instead of using two labels and it seems to be the same thing going on here...

    I'm wondering is there any way I could do something like this that I think would resolve the issue...

    Panel1.Controls.Add(Product_Label);
    Panel1.Controls.Add(CreateTheControls);
    CreateControls = true;
    //CreateTheControls();



    I'm getting an error when I do that as I can't just use a function like that with a control but if I could do something like this, I think I'd basically be appending the container as opposed to what I'm doing at the moment which is a bit messy...


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    I think you've done things a bit strangely here and it's adding to your confusion. You've put your logic that populates the item description into your button event handlers, and the code that adds the delete button in the page load.

    The delete button is being added twice because a page loads twice when you click a button. The first is to recreate the page, and the second is to process the button click event. You handle this by checking against the IsPostback property to see if you should add the controls.

    If it isnt a postback, then you should add the controls. If it is, you don't.

    The quickest way of saying this is:
    if(!IsPostback)
    {
    if (CreateControls)
    {
    CreateTheControls();
    }
    }
    

    This will probably solve the Delete button being added twice, but I'd recommend you handle things more logically. The two are linked to each other, if there's an item then there's a delete button.

    If you had a function called PopulateCart, which adds the text & description, and then calls the function to add the delete button it would make a lot more sense. You could also pass the information needed to create the delete button to the function, and this would safe a trip to the server & DB.

    Then you could call the PopulateCart function within you IsPostback check given above in the page Load function.


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    I am sorely tempted to write the correct code for you so that you can see how its done...

    A silly question now is why is all this info not in a datagrid so that you can do CRUD ops on it?


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Ginger wrote: »
    I am sorely tempted to write the correct code for you so that you can see how its done...

    A silly question now is why is all this info not in a datagrid so that you can do CRUD ops on it?

    Yeah, or a Repeater as you suggested earlier. Would make things a lot easier


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    I will see what I can do over the weekend for you.. being honest, its not a bad exercise for me

    Tho I have done the whole adding custom controls at runtime, this is not something that requires it...

    All you need is a list of items and when you want to delete it, you need to just know the ID to delete, ideal job for a repeater or the OOB datagrid which you can put the insert, update and delete options into by using the DataBind() method.

    http://www.dotnetjunkies.ddj.com/Article/24D5D73F-F941-4A70-B064-3195B8C039E7.dcik for example shows the whole thing like you might want to do

    You can put all the shopping cart in as a generic list in session (or db) and then retrieve so that they can edit amounts, delete for example

    Possibly a bit late in the day to be suggesting it tho


  • Advertisement
  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    My approach with C# up until this experience has been woeful!!! I've never used functions, wherever I could, I just horsed everything into the Page_Load until I had to use a Button_Click event handler, and how I got through two years of C in 3rd level I'll never know!

    I'm going to try approaching this problem more logically over the weekend and using one function to populate the cart and another one to delete items from the cart. I can't thank the two of you enough for your help with this, I'll have to set up a little drinking fund for a night on the tiles for yiz! ;)


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    My approach with C# up until this experience has been woeful!!! I've never used functions, wherever I could, I just horsed everything into the Page_Load until I had to use a Button_Click event handler, and how I got through two years of C in 3rd level I'll never know!

    I'm going to try approaching this problem more logically over the weekend and using one function to populate the cart and another one to delete items from the cart. I can't thank the two of you enough for your help with this, I'll have to set up a little drinking fund for a night on the tiles for yiz! ;)

    Perhaps you should try using an ASP.net control for this? It might show you how handy the out of the box controls are... think you probably need to see the benefits of this framework before you lose hope!

    As suggested above, try using a Repeater control and bind it to the Datatable or DataSource returned by your SQL.
    <asp:Repeater id="rptCart" runat="server">
    <ItemTemplate>
    <asp:Label Text='<%#DataBinder.Eval(Container.DataItem, "Item_Text")%>' runat="server" CssClass="AStyle"/>
    <br/>
    <asp:Button Text="Delete" OnClick="DeleteFunction" CommandArgument='<%#DataBinder.Eval(Container.DataItem, "ID")%>'/>
    </ItemTemplate>
    </asp:Repeater>
    

    There's no shortage of documentation on how to use this control so give it a shot. Obviously you do the binding in it's own function and call that within Page_Load and check against Postback like I pointed out earlier.

    Don't worry about the work you've already put into this, what you've learned wont go to waste!

    You could add a button


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Right, I've just copied a back up for my old solution and wiped the slate clean! Is the basic idea here to use a datalist???


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    Right, I've just copied a back up for my old solution and wiped the slate clean! Is the basic idea here to use a datalist???

    I usually work with the DataTable datatype. You'll need in import System.Data to use it though.

    Once you populate your datatable with the contents returned by your SQL, you can bind it to the repeater using:
    rptCart.DataSource=dt;
    rptCart.Databind();
    

    dt is your datatable.


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Right he is what you could do

    You can create a new project for example called common which contains your classes describing your objects

    for example

    A car class

    public class Car
    {
    public int Id {get;set}
    public string Make {get;set;}
    public string Model {get;set;}
    public string Price {get;set;}
    }

    You can then decide if you want a data layer, business layer or just hop everything together in your ASP.NET code (normally I do n-tier I just find it tidy)

    If you use a data layer you can for example create a function called GetAllCars(string Make)

    like so
    public static List<Car> GetAllCars(string make)
    {
    List<Car> cars = new List<Car>();

    //Get a dataset of all cars for a particular make

    foreach(Datarow row in DataSet.Tables[0].Rows)
    {
    List.Add(new Car{
    Make = row["Make"].ToString(),
    Model = row["Model"].ToString()
    //and so on

    });

    return cars;
    }


    This will create a List of cars you can show for example

    Now using John_Mc's repeater

    YourRepeater.DataSource = GetAllCars("Mazda");
    YourRepeater.DataBind();

    Now in your repeater you would have

    <%# ((Car)Container.DataItem).Make%> would show the make

    You could arrange said info in a table and it would show the cars details and you can also add other controls to do deletes updates etc.

    Now if you use a datagrid, its the exact same thing

    DataGrid.DataSource = GetAllCars("Mazda");
    DataGrid.DataBind();

    Now with the DataGrid you can add the options for updates and deletes using the commands, enableupdates, enabledeletes in the designer.

    You then just need to add the event handlers that will do that and how to do that is posted a couple of posts ago..

    HTH


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    I've did a bit of Googling and I found this which looks like it sets me up with a DataTable and it's compiling for me no bother...

    private DataTable CreateDataTable()
    {
    DataTable myDataTable = new DataTable();

    DataColumn myDataColumn;

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "id";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "username";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "firstname";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "lastname";
    myDataTable.Columns.Add(myDataColumn);

    return myDataTable;
    }

    So I just adapt the columns to match up with my SQLDB? Then I just have to populate my DataTable, do I use a datareader to do this???


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    I have a sample project that does something similar and I will upload it here for you.

    Its a pure skeleton but shows a repeater being databound for example and also shows it with Common objects, DataLayer, Business and a handy little trick of filling objects if you have named the properties the same in the database :)
    (solution removed)


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Ginger wrote: »
    I have a sample project that does something similar and I will upload it here for you.

    Its a pure skeleton but shows a repeater being databound for example and also shows it with Common objects, DataLayer, Business and a handy little trick of filling objects if you have named the properties the same in the database :)

    Pm for password

    Jasus that looks seriously complicated!


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    I've did a bit of Googling and I found this which looks like it sets me up with a DataTable and it's compiling for me no bother...

    private DataTable CreateDataTable()
    {
    DataTable myDataTable = new DataTable();

    DataColumn myDataColumn;

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "id";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "username";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "firstname";
    myDataTable.Columns.Add(myDataColumn);

    myDataColumn = new DataColumn();
    myDataColumn.DataType = Type.GetType("System.String");
    myDataColumn.ColumnName = "lastname";
    myDataTable.Columns.Add(myDataColumn);

    return myDataTable;
    }

    So I just adapt the columns to match up with my SQLDB? Then I just have to populate my DataTable, do I use a datareader to do this???

    Yeah exactly, within your While loop that iterates through the DBReader, you'll need to create a new row in the datatable. I forget exactly how to do this, but you're not just creating a datarow, you're creating a datarow for that datatable so that it has your column scheme.

    Google should give you a result on this. I had to do it recently myself.

    Once you have a new row, simply add your SQL column value to the corresponding column in myDataTable.

    I'd suggest using Gingers project as a template, it's definitely a good idea and best practice to seperate your logic into Data access, business rules and then you're logic in the code behind files. So instead of putting the code above in your code behind file, put it in a Dataclass and make it publicly accessible.


  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    Darragh29 wrote: »
    Jasus that looks seriously complicated!

    Take it one step at a time, but this is the structure of your web application that you should be aiming for!


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 2,791 ✭✭✭John_Mc


    code to create a new row:

    myRow = myDataTable.NewRow();


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Ok

    to explain

    You have a project called common, which contains my class representation of the data eg Player

    This project is referenced by all the other projects so that any changes to my definition of a class is automatically recieved.

    So the way that this works is so

    ASP.NET references Business which references DataAccess

    The only way for my ASP.NET to get its information is via the Business layer, meaning I can change the whole way the database works and just change only 1 section.

    As well as that, it means that the whole database thing is abstracted away, which is a very good thing. To get a list of Players, I just say GetAllPlayers() and thats it. It works.. no checking for open connections, no messing with configs. I just tell it what I want :)

    Now the database helper class takes care of access the database, opening and closing connections and returning information to my functions in the dataaccess project. That in turn, turns them into objects such as Player or Lists and sends them back to the Business project which sends them to the ASP.NET app so that it can run happy.

    In the DataAccess project there is a class called Common, which has 2 functions. These fill my objects using Generics..

    What I do, is I pass in an object eg Player and tell it to find out what public properties it has and to take the data from the row in the dataset and match it to the property names.

    What makes this a very handy function is that if I name my Fields in the database the same as the properties in my class, i can just populate the info very quickly and just use 1 function without having to write a function for each object type..

    Its complex if you dont see how it all hangs together....

    But step through the code from the ASPX page it will show how it gets to the database and back and how you end up with lists of objects rather than datasets


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    When I try to run that demo site, I'm getting this error...

    It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Right ok, you are probably running on IIS, I run mine on Cassini (the dev web server)

    Right first question running on IIS? You need to configure the virtual folder as an application

    If its not that

    Second question, are you running in a folder and and is there a web.config above that folder... IE is there 2 web.configs in the same path


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger




  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Ginger wrote: »
    Right ok, you are probably running on IIS, I run mine on Cassini (the dev web server)

    Right first question running on IIS? You need to configure the virtual folder as an application

    If its not that

    Second question, are you running in a folder and and is there a web.config above that folder... IE is there 2 web.configs in the same path

    I just created a new website and copied your files into it and that seems to have sorted out the problem there. Even just seeing this working is enough to make me want to go out for a few pints to celebrate!!!

    I have to pop out for an hour or two for a meeting but I'll be back later pulling that solution you gave me apart! Thanks again so much to the both of you... Beers on me in Dublin!


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Just realised I didnt supply a database if you are using SQL Server 2008 I can send you the files, otherwise I will create an SQL script for you with all the procs and logins etc

    N


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Ginger wrote: »
    Just realised I didnt supply a database if you are using SQL Server 2008 I can send you the files, otherwise I will create an SQL script for you with all the procs and logins etc

    N

    I'm using MS SQL Server 2005. I think I can knock that bit of it together though....


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    PM sent with script, just create your own user and database


  • Advertisement
  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    What I'm trying to do now is pull asunder the code I have that adds stuff to my cart (DB up until now), and get it to add items into this new datatable that you gave me...


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Righty then

    Create a new class in the folder entities in Common

    Call it CartItem and make it public (similar to the Player or News classes)

    Build it up to match your database entity (row)

    Add a new Class in the DataAccess project and class it CartItemDal.cs

    Make the class public

    Create a method called public void Save(CartItem obj)

    In the Save method

    Make it up similar to this one
    public void Save(CartItem obj)
            {
                SqlParameter[] sqlParameters = {
                                                   DbHelper.MakeInParam("ParamName1",SqlDbType.VarChar,250,obj.ParamName1),
                                                   DbHelper.MakeInParam("ParamName2",SqlDbType.VarChar,5000,obj.ParamName2)
                                               };
                var dbHelper = new DbHelper();
                dbHelper.RunProc<int>("usp_insert_CartItem", sqlParameters);
                dbHelper.Dispose();
            }
    

    Replace the ParamName1 and 2 with your items and add more if you need them. Also change the SqlDbTypes and lengths to match what you need

    Now in the Business project,

    Add a new class to the project and call it CartItemBl.cs

    Make the class public

    Create a new static method call Save(params....)

    Eg
     public static void Save(string P1,string P2)
            {
                var CartItem= new CartItem {Param1= P1, Param2 = P2};
                var CartItemDal = new CartItemDal();
                CartItemDal.Save(news);
            }
    

    Now in your aspx file, on your say button click event to save
    var P1= P1.Text;
                var P2 = P2.Content;
                CartItemBl.Save(P1,P2);
    

    You will need to add the using statements as you go along (or if you are using VS2008 do ctrl + . to shortcut it)

    So in order

    CartItemDal (using Common.Entities)
    CartItemBl (using Common.Entities & DataAccess)
    ASPX file (using Business)

    And finally you need to create the stored proc to save the stuff but that ok?

    Jobs done


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    I swear when I get this finished, I'll never defile a computer with my presence again! :D:D:D


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Can I not just create a datatable in my ButtonClick event handler???


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    You can but its not the way to do it

    What I suggest is that your shopping cart become a list<CartItem> in a Session

    Meaning that you hold the item, the amount and unit cost in an object

    When you click add to cart, you see if there is a list in session and if there is assign it to a new temp list in your page. If its not there create a new list


    Create a cart item and add it to your created list above

    Copy the list into session and you are done

    To display your shopping cart, bind a repeater or datagrid to the list in session and thats it!


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Could you send me on that solution you put up earlier??? I don't know what happened to teh one I downloaded earlier, but all I have now is one folder called demosite with default.aspx and default.aspx.cs pages that will build a 4 item cart and let me delete the items if I click on "Remove Item"... Is that the same solution I got from you earlier??? :confused::confused::confused:


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Pm your email and I will send it on


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Oki doki

    I created a shopping cart demo for you.

    Consists of 2 pages. Catalog and ShoppingCart

    Catalog displays all the products and allows you to add them to your cart.

    ShoppingCart shows the contents of your cart and alls you to remove them from the cart.

    Its extremely basic, I wrote it in about 2 hours over brekkie so there is feck all error handling in it ie none.

    Targetted for .NET 2.0 and built using VS 2008. You can import the projects one by one into VS2005.

    Just create a blank solution and and the projects in the following order

    Common
    DataAccess
    Business
    ShoppingCartDemo (ASPX Site)

    You will possibly need to readd the references

    DataAccess references Common
    Business references Common and DataAccess
    ShoppingCartDemo references Business and Common

    Code is commented somewhat to make it easier to understand.

    DB Script to recreate the database and procs included. Add some data.

    Now you will need to adjust your connection string.

    HTH


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    Ginger wrote: »
    Oki doki

    I created a shopping cart demo for you.

    Consists of 2 pages. Catalog and ShoppingCart

    Catalog displays all the products and allows you to add them to your cart.

    ShoppingCart shows the contents of your cart and alls you to remove them from the cart.

    Its extremely basic, I wrote it in about 2 hours over brekkie so there is feck all error handling in it ie none.

    Targetted for .NET 2.0 and built using VS 2008. You can import the projects one by one into VS2005.

    Just create a blank solution and and the projects in the following order

    Common
    DataAccess
    Business
    ShoppingCartDemo (ASPX Site)

    You will possibly need to readd the references

    DataAccess references Common
    Business references Common and DataAccess
    ShoppingCartDemo references Business and Common

    Code is commented somewhat to make it easier to understand.

    DB Script to recreate the database and procs included. Add some data.

    Now you will need to adjust your connection string.

    HTH

    Just after seeing this... Wakey wakey here!


  • Closed Accounts Posts: 7,097 ✭✭✭Darragh29


    I tried opening that solution using MS Dev 2005 but I had the same problem I had last night with opening it so I tried opening using MS Dev 2008 and it will compile grand there. What I'm getting now is an SQL connection error, I'm going to try connecting it up to my own DB and see if I can see the solution in motion!


  • Registered Users, Registered Users 2 Posts: 2,931 ✭✭✭Ginger


    Yup..

    In the web.config file change the connection string to whatever you need it to be


  • Advertisement
Advertisement