Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on [email protected] for help. Thanks :)
Hello All, This is just a friendly reminder to read the Forum Charter where you wish to post before posting in it. :)

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

1246789

Comments

  • Registered Users 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 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 Posts: 2,931 ✭✭✭ Ginger


    Pm your email and I will send it on


  • Registered Users 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 Posts: 2,931 ✭✭✭ Ginger


    Yup..

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


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


    Just one question here... Do I have to create the actual DB on my remote server??? I see the SQL script to create tables, etc, but do I need to create the actual DB first??? If I do, what do I need to call it???


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


    The sample relies on the database to get the product info

    So if you are running this on your desktop and have an SQL 2005/2008 server installed (any edition), just use the scripts to create the database and then modify the connection string to suit the changes eg change the name of the database andor/usernames and passwords

    You may need to create your own user for this database and give them execute rights on the database you created

    The script also creates the 2 stored procedures that the return the data

    Now if you are doing this on the remote server, just use whatever tools they suggest in their Help/FAQ


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


    You call the database whatever you like, just change the name in the the connection string

    In the web.config you will see

    <connectionStrings>
    <add name="default" connectionString="Data Source=localhost;Initial Catalog=ShoppingCartDemo;User Id=ShoppingCartDemoUser;Password=password;"/>
    </connectionStrings>

    Change the Data Source to the name or IP of the server or whatever the hosting company says it should be

    Change Initial Catalog to the name of your database

    Change the User Id to the name of your user that will have access to the database and similarly the password


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


    Right, its all hooked up and working now! I'm just trying to get my head around what is going on behind the scenes, and especially what happens between the Shopping Cart Demo folder and the other three folders: Common, Business and DataAccess... I've never seen a project working as it was meant to structured and approached as this one has been, although I read a small bit about Data Access Layers and Business Logic Layers and that stuff although I'lll have to read up on it all again...

    Before I go pulling the solution apart, I want to just look at what is happening and see if I can get a broad understanding as to how it all hooks up together...


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


    Righty then

    I will go through the Catalog.aspx file for you and show it all works

    Firstly you need to look at the project called common. It contains 2 classes. Product and CartItem
        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public int Cost { get; set; }
        }
    
       public class CartItem : Product
        {
            public int Amount { get; set; }
        }
    
    

    The product class represents strangely enough the product with a Name, Description and Cost etc. CartItem inherits (gets the same) these properties from Product and add its own property called Amount. This allows us to have a number of the same products in the cart and just to hold an amount value for them.

    These classes are common to all the projects in the solution (hence the project name common).

    Now in Catalog.aspx, it has just a couple of things on it. One is a repeater which shows the data the way I want it.

    So if you look at the repeater in the source code of the aspx fille you see
    <asp:Repeater ID="_Catalog" runat="server">
        <HeaderTemplate>
        <table>
        <tr>
        <td>Name</td>
        <td>Description</td>
        <td>Cost</td>
        <td>&nbsp;</td>
        </tr>
        </HeaderTemplate>
        <ItemTemplate>
        <tr>
        <td><%# ((Product)Container.DataItem).Name %></td>
        <td><%# ((Product)Container.DataItem).Description %></td>
        <td><%# ((Product)Container.DataItem).Cost.ToString(CultureInfo.InvariantCulture) %></td>
        <td><asp:Button ID="_AddToCart" CommandArgument="<%# ((Product)Container.DataItem).Id.ToString() %>" CommandName="AddToCart" runat="server" Text="Buy this" /> </td>
        </tr>
        </ItemTemplate>
        <FooterTemplate>
        </FooterTemplate>
        </asp:Repeater>
    

    What a repeater does, is it takes a datasource, in our case a list of products and outputs them in the way that we define it in the <ItemTemplate> part of the repeater.

    You will see that I have a HTML table row (tr) and a couple of cells in which I put the different values using the Container.DataItem function... except I tell to make it into a Product class so I can access the properties easier
    <%# ((Product)Container.DataItem).Name %>
    

    Now the final trick is the button.
    
    <asp:Button ID="_AddToCart" CommandArgument="<%# ((Product)Container.DataItem).Id.ToString() %>" CommandName="AddToCart" runat="server" Text="Buy this" />
    

    What this does is the following. I tell it to send the Id of the product back using the CommandArgument part of the code and I tell it that I want the command it sends back to be AddToCart. I could change this to any value I want.

    So every product in the list outputs a Name, Description and Cost and a button with its Id as the command argument in a seperate table row.

    Now into the code behind of Catalog.aspx

    The first thing that happens when you enter the page is that I assign a handler to catch the events from the repeater.
    protected override void OnInit(EventArgs e)
            {
                //Add an event handler to handle our button events in the repeater
                _Catalog.ItemCommand += CatalogItemCommand;
    
                base.OnInit(e);
            }
    

    This catches when the button is clicked.

    Next thing is that the Page_Load event fires.
          protected void Page_Load(object sender, EventArgs e)
            {
                //Only bind the first time
                if (Page.IsPostBack) return;
                _Catalog.DataSource = ProductBl.GetAllProducts();
                _Catalog.DataBind();
    
                _CartSize.Text = Session["Cart"] != null ? ((List<CartItem>) Session["Cart"]).Count.ToString() : "0";
            }
    

    I check to see if the page is a postback because I dont want to rebind the data everytime, only the first time.

    My DataSource for the repeater is a function in the ProductBL (Business Layer). It returns a generic list of products.
    public static List<Product> GetAllProducts()
            {
                ProductDal productDal = new ProductDal();
                return productDal.GetAllProducts();
            }
    

    The function GetAllProducts in the ProductBl is basically a pass through to the DataAccess project. Because I have minimal business logic in this solution I dont really need a Business layer but I put it in just to show how its done.

    The GetAllProducts function in the DataAccess project (ProductDal.cs) does the following.
    public List<Product> GetAllProducts()
            {
                DbHelper dbHelper = new DbHelper();
    
                DataSet dataSet = dbHelper.RunProcDs("usp_select_allProducts");
    
                return Common.CreateList<Product>(dataSet);
            }
    

    Firstly it creates a DbHelper object which manages all my connections and interactions with the database. By using something like this helper object I dont need to do all the same open db stuff every time.

    I create a dataset and tell it that its to be filled from the RunProcDs command in the helper. I tell it run the stored procedure usp_select_allProducts.

    This stored proc is simply the following SQL
    SELECT Id,[Name],Description,Cost FROM Product
    

    I then use another one of my helper classes. This one takes a dataset and creates a list of objects from that data. This function is located in Common.cs file.

    It does this using a trick called Reflection. In .NET you can find out all the property names of an object. So get all the names of the properties of the object I want to create, in this case Product, which is Id,Name,Description and Cost. See the names of the properties in the class are the same as the names of the columns in the database.

    So I tell it to loop through all the properties in the class and put the value of the column with the same name into the property. Eg

    Product.Id = datarow["Id"]

    And because the data type of the property and the one in the database are the same it works happily.
            internal static T CreateObject<T>(DataRow row) where T : new()
            {
                PropertyInfo[] propertyInfos = typeof (T).GetProperties();
    
                T obj = new T();
    
                foreach (var info in propertyInfos)
                {
                    info.SetValue(obj, row[info.Name], null);
                }
    
                return obj;
            }
    
            internal static List<T> CreateList<T>(DataSet dataSet) where T : new()
            {
                List<T> list = new List<T>();
    
                foreach (DataRow dataRow in dataSet.Tables[0].Rows)
                {
                    list.Add(CreateObject<T>(dataRow));
                }
    
                return list;
            }
    

    How do I tell it what object to create. Using a technique known as Generics, I can tell the program to expect some type of object and to work with that.

    So in the function CreateObject for example, I tell it that it will be an object of type T (ie I dont know), and that I will let it know at runtime.

    The reason for using Generics means I dont need to create a function for each object, which if you are using a lot of objects that would be a lot of repeated code.

    At this stage the DataAccess project has a list of products and returns that to the Business project which in turn returns it to Catalog.aspx. This looks like a long trip but because everything is designed to just get the job done its very quick.

    The repeater binds to this list and the stuff in ItemTemplate tells it how to show it.

    With me so far??

    Right then, on to the all important button that adds stuff to the cart.

    When you click the button, the page does a postback, and because I have an event handler to handle anything that happens in the repeater, it goes in there. (It doesnt rebind because we check for that)

    So the code for the function is
    private void CatalogItemCommand(object source, RepeaterCommandEventArgs e)
            {
                if (!Equals(e.CommandName, "AddToCart")) return;
    
                //Check if the session is null and assign the correct list
                List<CartItem> cartItems = Session["Cart"] != null ? (List<CartItem>) Session["Cart"] : new List<CartItem>();
    
                //Get the item I want from the database.
                CartItem cartItem = ProductBl.GetItem<CartItem>(Convert.ToInt32(e.CommandArgument));
    
                // This section can be used if you wanted to see if there was an item matching.
                CartItem hasitem = cartItems.Find((delegate(CartItem ci) { return ci.Id == cartItem.Id; }));
    
                //If the item exists, get its current amount and add 1. Then remove it
                if (hasitem != null)
                {
                    cartItem.Amount = hasitem.Amount + 1;
                    cartItems.Remove(hasitem);
                }
                else
                {
                    cartItem.Amount = 1;
                }
    
                //add our item to the cart with its correct amount
                cartItems.Add(cartItem);
    
                //put the cart back into the session state
                Session["Cart"] = cartItems;
    
                //This displays the size of the list which is the number of items but not the quantity
                _CartSize.Text = cartItems.Count.ToString();
            }
    

    What I do first is check what type of command I am getting, ie AddToCart. If you have a couple of different buttons or linkbuttons or whatever you could use that check to find what code to run.
    List<CartItem> cartItems = Session["Cart"] != null ? (List<CartItem>) Session["Cart"] : new List<CartItem>();
    

    Now the next line creates a new list of cartitem and assigns the value either to a new list or the list in my session. The syntax that it uses is just shorthand.

    So now I have a list of cartitem.
    CartItem cartItem = ProductBl.GetItem<CartItem>(Convert.ToInt32(e.CommandArgument));
    

    I create a new cartitem by using the function caaled GetItem and pass in the id of the product I want. This Id is the CommandArgument that i set in my button. The getting the details works the exact same as getting the list as described above.

    Now the next bit is a bit funky.

    I want to see if the person already put the same product in the cart and if they did, I want to increase the quantity by 1.

    So I create a new cartitem and try to find it in my list. If its there, it will come back as the same object otherwise it will be null.

    So I check to see if my hasitem is null and if its not, I add 1 to the amount and then I remove it from my list so that I only add the object once. You will see why in a minute.

    If the hasitem is null, I just use my new cartitem above and set amount to 1.

    After all that, I have a cartitem that has the correct amount and add that to the list.

    I then put the list back into the session (or for the first time it doesnt matter) and then I set the label to the count size of the list, which isnt the actual number of items but just the number of items in the list eg if you have 2 products with amounts of 2, it wont show 4, it will only show that you have 2 items because its using the count on the list.

    So that is the catalog page explained.

    I will do ShoppingCart in the next post!


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


    Now for ShoppingCart.aspx

    Again we are using a repeater in much the same way as we are using it in catalog. In this case I have 2 buttons, one is Update and the other Remove.

    They are different in a respect to the add method in Catalog.aspx because they dont contain a CommandArgument because it is not needed.

    The reason for this, is because we are using our own maintained list. ie we know where everything is.

    The update button doesnt do anything but is just there to show you can have more than 1 button.

    So the Repeater definition looks like this
      <asp:Repeater ID="_Cart" runat="server">
        <HeaderTemplate>
        <table>
        <tr>
        <td>Name</td>
        <td>Description</td>
        <td>Cost</td>
        <td>Amount</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        </tr>
        </HeaderTemplate>
        <ItemTemplate>
        <tr>
        <td><%# ((CartItem)Container.DataItem).Name %></td>
        <td><%# ((CartItem)Container.DataItem).Description %></td>
        <td><%# ((CartItem)Container.DataItem).Cost.ToString(CultureInfo.InvariantCulture) %></td>
        <td><%# ((CartItem)Container.DataItem).Amount.ToString(CultureInfo.InvariantCulture) %></td>
        <td><asp:Button ID="_Update" CommandName="Update" runat="server" Text="Update (no function)" /> </td>
        <td><asp:Button ID="_Remove" CommandName="Remove" runat="server" Text="Remove This" /> </td>
        
        </tr>
        </ItemTemplate>
        <FooterTemplate>
        </FooterTemplate>
        </asp:Repeater>
    

    In our page load, we bind the repeater to the List we have held in session. I check to see if the cart is there, in case of session timeout :)

    The reason I have a function called BindCart, is that I need to bind it again once I have deleted information so to save a couple of lines, I use the same function.

    Right the user clicks the update button, the CartItemCommand is run. Since I dont handle the Update command nothing happens.

    Click on delete and here is what happens
    void CartItemCommand(object source, RepeaterCommandEventArgs e)
            {
                //Check what button was pressed and do stuff
                if(e.CommandName=="Remove" && Session["Cart"]!=null)
                {
                    List<CartItem> cartItems = (List<CartItem>) Session["Cart"];
                    //since the session is a controlled list, just remove at the index
                    cartItems.RemoveAt(e.Item.ItemIndex);
                    //Assign back to session
                    Session["Cart"] = cartItems;
                    BindCart();
                }
            }
    

    I check to see if the Command is remove and that the cart is still in Session. Have to check each time otherwise you could get some dodgy errors.

    I create a list and copy the cart from the session to this list.

    I tell it to remove the item at a particular index, ie the index that it was in the repeater.

    Now this the bit. Both use 0 indexes lists ie the lists start counting from 0. When you click the button, it sends the eventhandler some data included is the position in the index you clicked.

    So say you had 10 items in your cart, you would have a list from 0-9. If you clicked on the last item (index 9), it would send that data back to the eventhandler. Since the repeater and cart are synced you need to just delete at index 9 to remove the last one. Ok?

    So we just delete at the position that we need to do and copy the cart back into session and rebind the repeater. thats it.

    This technique wouldnt work if we were using sorting because the lists would be out of sync. In the case of adding sorting you need to add the command argument with the id and then find the object with that ID in the list.

    That is how simple it is.


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


    Just sent ya an e-mail there Ginger...


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


    Hi

    Going to reply to the message on the forum. Just easier for people to see

    Ok

    To use your dropdown selection with the Catalog.aspx file you will need a new method in DataAccess eg
    public List<Product> GetAllProducts(string catName)
            {
                SqlParameter[] sqlParameters = {
                                                   DbHelper.MakeInParam("CatName", SqlDbType.Varchar, 50, catName)
                                               };
                DataSet dataSet = new DbHelper().RunProcDs("usp_select_AllProductsByCat", sqlParameters);
                return Common.CreateList<Product>(dataSet);
            }
    

    This will return a list of products by Category. Modify it so that you can pass in how ever many arguments you need to get your data back.

    Now you see how the page for Shopping cart is done at the moment in that project.

    You can copy the repeater from that page into your MainText.aspx and replace where you currently show the shopping cart.

    You will need to modify the code behind to add a repeater event handler (the part in the OnInit).

    Now when you click purchase, you can use the exact same logic I am using to add to the list, but after that, you need to bind the ShoppingCart repeater to the Session and you will then have a delete button for each item. If you want to change it to a link button that is fine too the same logic still applies here.

    Now you might need to change the Product class in Common to match your database structure, which quickly looking at what you show in the catalog is

    Retail_Price, Product_Description and Component_Manufacturer and hopefully(!!!) some ID field..

    You will only need to change 1 class, and add some stored procs, and change the repeater to use the new property names to make this work.

    So in a nutshell

    On MainTest.aspx

    Once you get the value of DropDownList3 (the Engine dropdown), pass that value to the function to get your list of products that match (in your case, I see you pass all 3 vars in)

    Eg if you were to use a repeater for this part, you would do something like this
    
    function that handles DropDownList3 SelectedItemChanged
    
    CatalogRepeater.DataSource = Business.GetAllPoducts(DropDownList3.SelectedValue); //change to use all 3
    CatalogRepeater.DataBind();
    
    

    Replace all the code that currently show the Product catalog with a repeater, designed the same way that it is use in the Catalog.aspx page.

    This would display the list of Products for that engine in this case. Each would have a purchase button with the ID of the product and you would be able to use the same logic as in Catalog.aspx. Just change the names you use in the class eg Description now becomes Product_Description, Cost becomes Retail_Price and Name can be changed to the Component_Manufacturer

    Now in the function CatalogItemCommand

    You would add a new new bit after you add the List of Cartitems into Session to bind the ShoppingCartRepeater to that.

    Now to make this all easier to understand, I just recreated Catalog.aspx with the changes like this

    Its just both pages combined and the only change is that when you add an item to the cart, I bind the shopping cart.


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


    I'm gonna give this a shot, there's a river near my house and I can see myself jumping into it before this day is up! :D:D:D


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


    Is the approach with this meant to be that I continue to post in my 3 values from my dropdown list into my DB? Then when they are in there is it that I bind my application to the DB values posted after my Button1_Click event???


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


    Button 1 is the purchase button isnt it

    Ok the way that I would do this, is the following

    You will notice there are 2 repeaters on the new Catalog.aspx page.

    I am going to be very blunt and tell you to use a repeater and scrap your previous methods as its not good, confusing the crap out of you and its easier to see what is happening with this code (a lot less spaghetti!) I dont normally tell people to do this :)

    Where you normally outputted your car part and session info, remove it. Remove your purchase button as well, basically I want all the stuff including what is in the DropdownList3 SelectedIndex changed removed. Keep Ddl1 and 2 as is they are ok for the moment.

    Use the repeater sample I gave you and edit the item template to output the information how you want.

    In the database create a new stored procedure that gets back the list of products eg From your code

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

    CREATE PROCEDURE dbo.usp_select_product
    (
    @Make VARCHAR(200),
    @Model VARCHAR(200),
    @Engine VARCHAR(200)
    )
    SELECT etc etc

    Now create a method in DataAccess that takes 3 string params and executes that proc and returns a list of information (similar to GetAllProducts is written)

    In Business create a method that takes 3 string params and returns a List<Product>, same as GetAllProducts

    Finally in your SelectedIndexChanged in DropDownList3 (assuming the repeater is called _Catalog)

    _Catalog.DataSource = Business.YourMethodName(string1,string2,string3);
    _Catalog.DataBind();

    This will output the data in the way you want, and give you a purchase button for each item.

    Now you can use the exact same code as in Catalog.aspx to put the items in the cart and show them in the Cart repeater.

    What I am trying to do here is simplify the whole process for you, so you can just databind and forget :)

    I am working on the idea that you are using the solution I provided as a base at this point.. If you are'nt it would be handy to know...


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


    Additionally, if you want to supply the database, I can do a bit on this, and probably show how this works ...


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


    Ginger wrote: »
    Button 1 is the purchase button isnt it

    Yip, the three Dropdown Lists are linked, so the idea being that by using the 3 Dropdown Lists, I can get make, model & engine type from a user. When I have that, I've posted these three pieces of info into my DB on Button1_Click.
    Ginger wrote: »
    I am going to be very blunt and tell you to use a repeater and scrap your previous methods as its not good, confusing the crap out of you and its easier to see what is happening with this code (a lot less spaghetti!) I dont normally tell people to do this :)

    I'm trying to keep with how you are approaching this so I can pick up the proper approach you've used, but I have to admit a lot of it is going over my head because I've been doing in my own half arsed way up until now!

    Where you normally outputted your car part and session info, remove it. Remove your purchase button as well, basically I want all the stuff including what is in the DropdownList3 SelectedIndex changed removed. Keep Ddl1 and 2 as is they are ok for the moment.

    Use the repeater sample I gave you and edit the item template to output the information how you want.

    In the database create a new stored procedure that gets back the list of products eg From your code

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

    CREATE PROCEDURE dbo.usp_select_product
    (
    @Make VARCHAR(200),
    @Model VARCHAR(200),
    @Engine VARCHAR(200)
    )
    SELECT etc etc

    Now create a method in DataAccess that takes 3 string params and executes that proc and returns a list of information (similar to GetAllProducts is written)

    In Business create a method that takes 3 string params and returns a List<Product>, same as GetAllProducts

    Finally in your SelectedIndexChanged in DropDownList3 (assuming the repeater is called _Catalog)

    _Catalog.DataSource = Business.YourMethodName(string1,string2,string3);
    _Catalog.DataBind();

    This will output the data in the way you want, and give you a purchase button for each item.

    Now you can use the exact same code as in Catalog.aspx to put the items in the cart and show them in the Cart repeater.

    What I am trying to do here is simplify the whole process for you, so you can just databind and forget :)

    I am working on the idea that you are using the solution I provided as a base at this point.. If you are'nt it would be handy to know...[/QUOTE]

    I am using the solution you provided but I'm going to be honest and say that a lot/most of it is going over my head! I'm just not fluent enough with asp.net and C# to get my head around what is happening. Some of the stuff I'm seeing here for the first time, repeaters, stored procedures, data access laters, business layers, etc... I was already on shaky ground with functions, arguments, and methods! :D:D:D


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


    Alrighty,

    Understood :)

    Send me on the table structure of you Vehicle_Data table and I can probably recreate the classes for this...

    Additionally its better with the dropdowns have the values as numbers rather than text values.

    Currently I am doing a refactoring project with another company and teaching them the same tricks :)


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


    Ginger wrote: »
    Alrighty,

    Understood :)

    Send me on the table structure of you Vehicle_Data table and I can probably recreate the classes for this...

    Additionally its better with the dropdowns have the values as numbers rather than text values.

    Currently I am doing a refactoring project with another company and teaching them the same tricks :)

    As rattled as I am with the new "proper" approach you're showing me, I'll eventually be able to make sense of it when I get my head around what bits of the solution are interacting with what other bits and it all starts sinking in...


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


    No worries, the main thing is to look at it a bit like this.

    You are creating a load of pieces that work together much in the same was an engine :) its looks complex to the untrained eye, but in reality its just a simple explosion provides energy eventually to move the wheels!

    And not to say you are untrained, you just need to learn how all the parts fit together!


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


    I'm spending tonight reading up on Classes, Methods & Objects, and tomorrow I'm going to read the whole thread again... I think this is where my problem is with this, when you say I need to write a class, I don't know really what a class does 'cos I never used on before in C#, I did years ago in C but that was just to do an exam, I never really understood what was going on!


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


    What I did tonight was refreshed my C# basics and also tried to bring over my old MainTest.aspx file and codebehind page into the solution that Ginger did for me. I had loads and loads of compilation errors mainly due to code missing from my web.config file, but I've got the page to compile now, except that I've a load of schema warnings (26 of em) and for some weird reason, all my labels and controls in my cs page are coming up as "Does not exist in the current context", although when I go to use intellisense, they are all there no problem and all the controls exist in my aspx page which I thought meant I could work on them anywhere in my cs page....

    :confused::confused::confused:

    What I'm trying to do here is now that I have my Dropdown Ajax 3 layer menu in the same project as Ginger's solution, I can start trying to tie the whole thing up together and see if I can get this working as I want to...

    Right, bed time...


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


    Ok

    Might I suggest something

    Go slowly

    Dont bring in old code in such a large chuck, it just adds to the problem..

    WHat you should do is create the dropdowns again and get them working so that they bring back the correct cascade sequence.

    Then start looking at binding the correct data to the repeater.

    Once you have done that you can skin the page and its nearly finished for you


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


    As for the errors, did you add the Test.aspx, the code behind file and the designer file when you added them to the solution


Advertisement