views:

156

answers:

3

It seems that Intellisense just doesn't work within attributes in an ASP.NET page. I really like strong typing, because I like Intellisense, and so I generally make sure to bind to a strongly typed object in ASP.NET:

<Repeater ID="rep" runat="server">
  <ItemTemplate>
    <div id="mydiv" class="<%# TypedObject.Class  %>" runat="server">
      <%# TypedObject.Name %>
    </div>
  </ItemTemplate>
</Repeater>

Intellisense just works within the body of the div, but no matter what I do it will not work to set that class attribute. This is very annoying, since attributes are pretty fundamental in HTML, and many of the built in controls use them heavily.

I can't find anything about this, but I can't believe this isn't a pretty fundamental need. Is there any way to get this to work?

A: 

To ensure proper Intellisense and strong typing, put your databinding code in the code file instead of the ASPX page. You will find your apps much easier to support should/when your typed object changes. The only "yellow" you should see in your ASPX page is at the top.

Your repeater should look like this...

<asp:Repeater ID="rep" runat="server">
    <ItemTemplate>
        <div id="mydiv" runat="server" />
    </ItemTemplate>
</asp:Repeater>

Your code file should look like this...

Option Explicit On
Option Infer On
Option Strict On

'Replace this class with your custom typed object'
Public Class TypedObject
    Public [Class] As String
    Public [Name] As String

    Sub New(ByVal NewClass As String, ByVal NewName As String)
        Me.Class = NewClass
        Me.Name = NewName
    End Sub    
End Class


Partial Class _Default
    Inherits System.Web.UI.Page

    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'Creating sample data and binding it to the repeater'
        Dim aData() As TypedObject = {New TypedObject("Class1", "Name1"), New TypedObject("Class2", "Name2")}

        rep.DataSource = aData
        rep.DataBind()
    End Sub

    Private Sub rep_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rep.ItemDataBound
        'Do not process headers/footers/separators'
        Select Case e.Item.ItemType
            Case WebControls.ListItemType.Item, WebControls.ListItemType.AlternatingItem
            Case Else
                Exit Sub
        End Select

        'Aquire our datasource for this row'
        Dim dr = DirectCast(e.Item.DataItem, TypedObject)

        'Aquire the control to bind (Do this for each control you are binding)'
        Dim mydiv = DirectCast(e.Item.FindControl("mydiv"), HtmlGenericControl)

        'bind the control'
        mydiv.InnerHtml = dr.Name
        mydiv.Attributes("class") = dr.Class

    End Sub
End Class

You should also consider using an <asp:Label> instead of a <div>. Then you can use the .CssClass property instead of .Attributes("class").

Carter
I know that I could do this, but it seems like the wrong approach for several reasons. It replaces one line of code with at least 10, and much of that code is casting and other things that are much more irritating than the original lack of Intellisense. Also, it would make it much harder to make changes later. If I wanted to replace the repeater with a grid, I'd have to make many non-trivial changes in the code behind. But most important, ASP (and WPF) are about being declarative as possible, and having as little procedural code as possible. This is going in the opposite direction.
Joshua Frank
I'd rather do 10 lines of code with intellisense, than one line of code without it. Is ASP.NET really about being as declarative as possible? Do not fear the code-behind. :-P
dave
I guess I think one should be as declarative as possible, but only because once you're declaring the template, any *other* place you put something is less tightly coupled, and that lets bugs in and makes things harder to understand. And those ten lines of code probably allow room for more problems too. Really, they just need to fix the designer so it works the way it's supposed to. FWIW, the designer in WPF/Silverlight seems to have largely fixed this kind of problem.
Joshua Frank
+2  A: 

I have same problem very often, even while working in asp.net mvc 2. Usually I just type code outside class (where intellisense works) and then just move that piece of text into attribute. :S

obrad
Sigh, that's what I do too, but it's so kludgy.
Joshua Frank
Same problem here in VS2010. Once its in quotes inside an attribute I get nothing.
jwsample
In MVC 2 aswell? :-( I was looking forward for improvements in this matter there.
joeriks
+1  A: 

It is really bad that Visual Studio 2008 / 2010 does not handle this. I sincerely hope it will come in the next release. However there are extensions out there that do help here.

Just tried Resharper for this particular reason and found it to be of great help. Both syntax checking and IntelliSense in my attribute strings now :-). I guess there are other Visual Studio extensions that do this aswell, havent tried just yet. (Resharper costs some, but they do have alternative free licenses for academic and open source dev.)

joeriks
I've heard many good things about Resharper, but never tried it. I've actually put down ASP.NET for a while, but when I get back to it, I could give that a try. Thanks.
Joshua Frank
Cheers! (Just got an answer from Coderush support about this "We do not provide our own IntelliSense window. We are using the built-in window for this purpose. So, I am afraid our tools cannot help in this situation.")
joeriks