Best way to custom edit records in ASP.NET? - asp.net

I'm coming from a Rails background and doing some work on a ASP.NET project (not ASP MVC). Newbie question: what's the easiest way to make a custom editor for a table of records?
For example: I have a bunch of data rows and want to change the "category" field on each -- maybe a dropdown, maybe a link, maybe the user types it in.
In Rails, I'd iterate over the rows to build a table, and would have a form for each row. The form would have an input box or dropdown, and submit the data to a controller like "/item/edit/15?category=foo" where 15 was the itemID and the new category was "foo".
I'm new to the ASP.NET model and am not sure of the "right" way to do this -- just the simplest way to get back the new data & save it off. Would I make a custom control and append it to each row? Any help appreciated.

You can REALLY cheat nowadays and take a peek at the new Dynamic Data that comes with .NET 3.5 SP1. Scott Guthrie has a blog entry demoing on how quick and easy it'll flow for you here:
http://weblogs.asp.net/scottgu/archive/2007/12/14/new-asp-net-dynamic-data-support.aspx
Without getting THAT cutting edge, I'd use the XSD generator to generate a strongly typed DataSet that coincides with the table in question. This will also generate the TableAdapter you can use to do all your CRUD statements.
From there, bind it to a DataGrid and leverage all the standard templates/events involved with that, such as EditIndex, SelectedIndex, RowEditing, RowUpdated, etc.
I've been doing this since the early 1.0 days of .NET and this kind of functionality has only gotten more and more streamlined with every update of the Framework.
EDIT: I want to give a quick nod to the Matt Berseth blog as well. I've been following a lot of his stuff for a while now and it is great!

There are a few controls that will do this for you, with varying levels of complexity depending on their relative flexibility.
The traditional way to do this would be the DataGrid control, which gives you a table layout. If you want something with more flexibility in appearance, the DataList and ListView controls also have built-in support for editing, inserting or deleting fields as well.
Check out Matt Berseth's blog for some excellent examples of asp.net controls in action.

Thanks for the answers guys. It looks like customizing the DataGrid is the way to go. For any ASP.NET newbies, here's what I'm doing
<asp:DataGrid ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="RuleID" Visible="False" HeaderText="RuleID"></asp:BoundColumn>
<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<!-- in case we want to display an image -->
<asp:Literal ID="litImage" runat="server">
</asp:Literal>
<asp:DropDownList ID="categoryListDropdown" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
This creates a datagrid. We can then bind it to a data source (DataTable in my case) and use things like
foreach (DataGridItem item in this.GridView1.Items)
{
DropDownList categoryListDropdown = ((DropDownList)item.FindControl("categoryListDropdown"));
categoryListDropdown.Items.AddRange(listItems.ToArray());
}
to populate the intial dropdown in the data grid. You can also access item.Cells[0].text to get the RuleID in this case.
Notes for myself: The ASP.NET model does everything in the codebehind file. At a high level you can always iterate through GridView1.Items to get each row, and item.findControl("ControlID") to query the value stored at each item, such as after pressing an "Update" button.

Related

Add SQL information to GridView column tooltip

I have been searching for hours and can not find a solution. i was wondering is there a way to add sql data to a tool tip in ASPX? At the moment i have a GridView which shows information from a database. The final column is a total column, i would like the tool tip to show how the total was got.
What would be the best way to do this? I am using vb codebehind for this project.
Thanks
Make the cell of your grid view that holds the total value be a server control, like Label, and then bind the text to the ToolTip property of control like this:
<asp:Label id="LabelTotal" runat="server" ToolTip='<%# Eval("Formula") %>' />
Obviously, this means you need to have a property named "Formula" in the list of objects you are binding to your grid view or a database column named "Formula".

Asp.Net page rendering and UI controls modularity

the website I'm currently developing can display dynamically-built forms.
A form is composed of fields, which are created directly by the users and can be displayed as one of multiple types that we support (text box, list box, tickbox, radiobuttonlist etc.). The rendering logic uses a repeater that iterates over a collection of all the fields defined by the user.
Inside the repeater (directly in the aspx page), one instance of each of the types we support is defined.
<asp:Repeater ID="fieldRepeater" runat="server">
<ItemTemplate>
<asp:TextBox ID="textBox" runat="server" />
<asp:DropDownList ID="dropDownList" runat="server" />
<asp:CheckBox ID="checkBox" runat="server" />
<asp:RadioButtonList ID="radioButtonList" runat="server" />
[...]
</ItemTemplate>
</asp:Repeater>
During the loading, we figure out which control is required and actively hide all the other ones.
Being still new to the web based development world, this approach seems very odd to me. My guts would prefer keeping the UI clean and instanciate exactly the controls that are required in CodeBehind and not start "playing" with visibility... but the current approach has some obvious benefits as well.
Is it really how one would do it in a web app?
Are there some best practices here?
Thanks!
I have no idea what the best practice is here, but I have done something similar before in a previous project and tried both approaches. Both will work.
Creating the controls in code-behind can be fiddly, especially if you are having to deal with post-backs. The controls have to be created in OnInit, as otherwise they won't get the posted form values and viewstate populated. This will cause complications if any of the control creation is based on the values of other controls, as you won't known the values without manually delving into the posted form values.
The only practical disadvantage with your current approach that I can think of is that all four controls (TextBox, DropDownList etc.) have to be instantiated and processed server-side by ASP.Net, which is a bit of a waste of resources. But it's probably not too significant; maybe do some profiling to see. I do agree that it seems a bit odd though, it doesn't feel very "clean".
As you said you're new to web development, then I would recommend continuing with your current approach of including all the controls and hiding the irrelevant ones. I just found it simpler when I did, even though it may not seem as nice.
Good luck!

turn sql rows into links on a vb.net page?

I am trying to create a specific aspx page where I display clickable links based on information in a sql database. For example one column could be the anchor tag another column could be the path to the link itself etc. In the past I would pull this information from sql and put it into a non-visible Label (say linkLabel1). Then in the page itself I would insert <%linkLabel1.text%> to insert the link path from the database to the appropriate area.
I hope I'm not confusing things too much here and that makes sense how I explained it.
What I would like to do is set up a way that I could simply enter a new row into a SQL table with link information and a web page automatically displays the new link for me.
I guess I am mostly looking for insight, opinions, or directions of what approach to consider. I can elaborate if I was unclear (wouldn't be awfully surprising if I was not).
Thanks in advance for anyone's time on this matter.
Since you are displaying this in a table, you could use a GridView for this. The columns that will display the link could be defined as hyperlink columns as so:
<Columns>
<asp:HyperLinkField
HeaderText="Header text"
DataNavigateUrlFields="PropertyContainingTheHRefForTheAnchor"
DataTextField="PropertyContainingTheTextForTheAnchor"
/>
</Columns>
So for example, if you return a record set containing these columns:
TextProperty PathProperty
See Details Assets/SomeOther/
Click me Products/AnotherPath/
Your grid will render these as:
See Details
Click me
If you define the column as:
<Columns>
<asp:HyperLinkField
HeaderText="Header text"
DataNavigateUrlFields="PathProperty"
DataTextField="TextProperty"
/>
</Columns>

Why is ASP.NET ViewState retained with an asp:dropdownlist but not an asp:table?

Alright, there is probably a super-obvious answer to this question for many of you, but it has me stumped.
I have an asp.net web form, and on it I have two controls (well, more than these two but we'll focus on these) - the first is an asp:dropdownlist and the second is an asp:table.
Both of these controls are declared on the HTML side, and filled (child controls added) in the code-behind page.
My simple question (hopefully with a simple answer) is this:
Why does the viewstate persist for the dropdownlist, and NOT for the table?
I have to fill the table on every page load, but I can fill the dropdownlist once (using Not Page.IsPostBack), and it persists.
NOTE: I have read about the lifecycle of ASP.NET pages, and I have tried placing these same calls in the Init() and PreInit() page events with the same results.
What obvious detail am I missing here?
Thanks for the help.
You're not missing anything, your assessment is correct. ASP.NET tables do not save their contents to view state.
I assumed at least part of the reason is that a table can contain any amount of any type of data and could really start to add to the size of the view state in some cases.
Either way, that's the way they work. If postbacks are possible on your page, you'll need to either repopulate the table on each load event, or store the table data to view state yourself and then repopulate the table from the data.
The asp:table object does not store its contents in ViewState, as it is not a data bound control. It works the same as an asp:panel in this regard; if you add controls to it programmatically, you need to do so on each post-back, or the items in it will not persist.
If you wanted to store the contents of the table in viewstate - which I woudln't recommend, but sometimes you need to do so ... you would just have to use the standard asp.net table control.
<asp:Table ID="Table1" runat="server">
<asp:TableRow ID="TableRow1" runat="server">
<asp:TableCell ID="TableCell1" runat="server">
This is Cell 1
</asp:TableCell>
<asp:TableCell ID="TableCell2" runat="server">
This is Cell 2
</asp:TableCell>
</asp:TableRow>
</asp:Table>
You can read more how to do this at http://weblogs.asp.net/nannettethacker/archive/2008/01/24/html-tables-to-asp-net-table-controls.aspx.
You might also try adding runat="server" to the table tag.
Not really answering your question directly, but thought it might be helpful nonetheless.

ASP.NET databinding / getting variables from codebehind

So I haven't used ASP.NET for three years or so and I'm really rusty on it. My old code isn't available to me for review (at an old company). This question should be pretty basic, but I can't find any good or reliable or not-super-old resources on the issue, so I'm asking here.
Can I get a general overview of databinding again? I remember it being really useful for select boxes, etc., but I don't really remember how it works. Maybe a good ASP.NET tutorial in general, because I don't remember how it handles POST requests or anything like that really either. Should I just try ASP.NET MVC?
Relatedly, suppose I have a public variable in my codebehind page. Right now I am accessing it by saying Page.DataBind() at the end of the page load function and then running <%# variable %> in the ASPX, but that's not how I remember doing it before and I reckon that it's not very good practice. What's the best way to display variables from codebehind?
Databinding in general (at least in the WebForms model) is mostly a case of assigning fields to be displayed, setting the DataSource property to a suitable object that contains those fields e.g. a DataReader, DataTable, a Collection, and calling the DataBind method. So for your select case, you'd put an <asp:dropdownlist runat="server" id="MyDropDownList"> in the markup for the page, and then in the code
DataSet myDataSet;
myDataSet = someDataMethod();
MyDropDownList.DataTextField = fieldname;
MyDropDownList.DataValueField = fieldname;
MyDropDownList.DataSource = myDataSet;
MyDropDownList.DataBind();
Or you can avoid writing that kind of code and do it in the markup if you use a DataSource control e.g. <asp:SqlDataSource>, <asp:ObjectDataSource>
<asp:SqlDataSource runat="server" id="MySqlDataSource" ConnectionString="aConnectionString" SelectCommand="MyStoredProcName" SelectCommandType="StoredProcedure" />
<asp:dropdownlist runat="server" id="MyDropDownList" DataSourceId="MySqlDataSource" DataTextField="fieldname" DataValueField="fieldname">
For putting your variable on a page, the way you might have done it before is to have a label or textbox on the page, that in your code-behind you assign your variable to the Text property e.g.
<asp:label runat="server" id="MyLabel" />
MyLabel.Text = myVariable.ToString();
Postbacks: you can test the IsPostback property of a page in code-behind to determine if it's a postback or not. After the Page_Load method, other methods will fire if you've defined them e.g. SelectedIndexChanged for a DropDownList.
I really wanted to answer this question with examples and code etc.. but I would just be rehashing information that has been on the web for years and been explained in blogs and articles countless times. You can start with this article
which explains almost everything you need to know.
I have bolded the ones that I think are important to note that some my skim over.
<%# %> Syntax
Page.DataBind() versus Control.DataBind()
Data-bound list controls
Repeater control
DataList control
DataGrid control
Accessing data
DataSet class
DataReader class
Binding in list control templates
DataBinder.Eval method
Explicit casting
ItemDataBound event
As for learning MVC over webforms, that is whole different story. They both have pluses and minuses depending on your time, what you NEED to know and what portions of the project are important. Both techs can accomplish the same thing as they are all ASP.NET at their core, just different approaches so you will be fine either way.

Resources