Xeddon
Xeddon

Reputation: 449

Call methods instead of property with Eval

Example:

I can access ID property because there is a property.

But I can't access a method from same class. So <%# Eval("GetToday") as string %> don't work. Creating a property instead of a method with no setter will solve the problem, but exist a better way?

Markup:

<asp:GridView ID="GridView1" runat="server" SelectMethod="GetMyClass">
<Columns>
    <asp:TemplateField HeaderText="ID">
        <ItemTemplate>
            <%# Eval("ID") as string %>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Today">
        <ItemTemplate>
            <%# Eval("**GetToday**") as string %>
        </ItemTemplate>
    </asp:TemplateField>
</Columns>

Code behind:

public IList<MyClass> GetMyClass() { return new List<MyClass>(); }

MyClass:

public class MyClass {
   public int ID { get; set; }
   public DateTime Date { get; set; }

   public string GetToday()
   {
       // other userfulls logic
       return Date.ToString("dd.MM.yyyy");
   }

   // workaround
   public string GetTime
   {
       get
       {
          return Date.ToString("HH:mm");
       }

       set
       {
          // nothing
       }
   }
}

Upvotes: 0

Views: 2928

Answers (4)

glboothby
glboothby

Reputation: 151

You are right that you could create a property with a get accessor if it is as simple a method as your example.

As philreed has pointed out if you are just formatting a DateTime then you could use Eval on the existing propery:

    <%# Eval("Date", "{0:dd.MM.yyyy}") %>

But if the method is doing something more complex then I would avoid putting complex logic inside a property. Instead you could call a method in the page's code behind that would then call your class's method:

    <asp:TemplateField HeaderText="Today">
        <ItemTemplate>
            <%# GetToday(Container.DataItem) %>
        </ItemTemplate>
    </asp:TemplateField>

Then in the code behind:

protected string GetToday(object obj)
{
    MyClass mc = obj as MyClass;
    if(mc != null) return mc.GetToday();
    else return "Some default text.";
}

Not the most elegant solution, but could be used if there is no other alternative.

Upvotes: 0

philreed
philreed

Reputation: 2617

You would be better off using the existing DateTime Date property you have and apply some text formatting:

<asp:GridView ID="GridView1" runat="server" SelectMethod="GetMyClass">
<Columns>
    <asp:TemplateField HeaderText="ID">
        <ItemTemplate>
            <%# Eval("ID") as string %>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Today">
        <ItemTemplate>
            <%# Eval("Date", "{0:dd.MM.yyyy}") %>
        </ItemTemplate>
    </asp:TemplateField>    
</Columns>

If you must have custom logic, then you can do this in the property instead of using a method, for example:

public class MyClass {
   public int ID { get; set; }

   private DateTime _date;
   public DateTime Date
   {
       get
       {
          //do something with the date field here

          // you could add a number of days for example
          _date = _date.AddDays(4);          

           return _date;
       };
       set
       {
           _date = value;
       };
    }   

    public MyClass()
    {
         _date = DateTime.Now();

    }
}

Just make sure the private _date field is initialised properly, perhaps in a constructor for MyClass, i've initialised it to the current date in the example.

Upvotes: 1

Crowcoder
Crowcoder

Reputation: 11514

You can call a method, you just have to get the syntax correct:

<%= GetToday() %>

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 156978

No, there is not. The ASP.NET Databinder.Eval method only supports property expressions, as stated in MSDN (emphasis mine):

The navigation path from the container object to the public property value

There is no alternative for the method call besides properties, which you have found out already.

Upvotes: 2

Related Questions