智能感知&强类型数据控件 - 没有更多错别字......?

时间:2012-09-05 23:37:18

标签: asp.net gridview webforms visual-studio-2012

我正在阅读ASP.NET 4.5 Web窗体功能,以了解新功能。我最近使用GridView尝试了强类型数据控件功能。但是,据我所知,当你使用 asp:TemplateField 时,你只能使用强类型的好处.....如下:

            <asp:TemplateField HeaderText="Name" >
                <ItemTemplate>
                    <%# Item.Name.ToString() %>
                </ItemTemplate>
            </asp:TemplateField>

这是真的吗?您不能在asp中使用强类型:BoundField,asp:DynamicField或GridView中的任何其他可能的列控件吗? 例如,当我放置一个标准的asp:BoundField时,它没有向我提供任何intellisense自动完成。我只能输入DataField属性的字符串。像这样:

<asp:BoundField DataField="JyooobTitle" HeaderText="Job Title" />

糟糕!看起来我在那里错误拼写了“JobTitle”,但编译器没有抓住它。因此,为了从强类型中受益,似乎我被迫使用TemplateField选项....对于每一个列是否需要它!

此外,如果你想在你的TemplateField上放置一个SortExpression属性....你必须希望你拼写那个也是正确的,因为它似乎没有强大的输入。希望我只是遗漏了一些明显的东西,因为这是一个很棒的新功能,但它似乎确实是只实现了一半

任何人都可以验证这是否属实......或者我是否遗漏了什么?

2 个答案:

答案 0 :(得分:0)

作为一个相对较新的ASP.NET开发人员,我可能没有足够的洞察力或经验来了解这个问题的完整答案,但我将对此问题给予最好的理解。我也使用了ASP.net 4.5“强类型模型绑定”。当我第一次通过Scott Hanselman的优秀video发现它时,它引起了我的注意。你提到的问题肯定是该功能的一个不幸的限制。但是,我认为我们应该感谢我们获得的帮助。

.aspx页面中考虑您的其他工作。虽然Intellisense确实提供了一些填充控制属性的帮助(例如Visible=的真/假下拉),但声明性标记的验证总体上是非常小的。这是其本质的一部分。它不是一个“编程”文档,而是一个语义文档。由于这个事实,它可以在不重新编译项目的情况下进行更改,这有时非常方便。

ASP.NET确实提供了一种方法,用于通过内联代码部分(&lt;%#%&gt;等)将实际编译的代码放入aspx标记中。强类型绑定利用了这些。它们就像是编程世界的后门,为您提供完整的智能感知体验。

我希望有一天我们可能会在DataField属性中看到强类型,但我不会在任何时候过早地查找它。现在,我会利用ItemType并随时为我的方便而欢欣鼓舞。

答案 1 :(得分:0)

以下是我解决排序表达式绑定问题的方法。

我没有将SortExpression设置为不动产名称,而是将其设置为列的序号位置。

<Columns>
    <asp:TemplateField HeaderText="Name" SortExpression="1" >
        <ItemTemplate>
            <%# Item.Name %>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Job Title" SortExpression="2" >
        <ItemTemplate>
            <%# Item.JobTitle %>
        </ItemTemplate>
    </asp:TemplateField>
</Columns>

然后,将处理程序附加到gridview的Sorting事件。

<asp:GridView runat="server"
              OnSorting="Sorting"
              ...

其中一个事件参数是您之前定义的排序表达式(即"1""2")。您可以使用此值以编程方式将排序表达式重新绑定到实际的属性名称。

注意:遵循此方法意味着放弃在升序/降序排序顺序之间自动切换。但是,重新实施它并不是特别困难。

注意:我使用基于反射的方法在执行时确定属性名称。

protected void Sorting(object sender, GridViewSortEventArgs e)
{
    int columnPosition;
    if (!int.TryParse(e.SortExpression, out columnPosition))
    {
        return;
    }

    switch (columnPosition)
    {
        case 1:
            e.SortExpression = Reflector.GetPropertyName<Employee>(o => o.Name);
            break;

        case 2:
            e.SortExpression = Reflector.GetPropertyName<Employee>(o => o.JobTitle);
            break;
    }

    var grid = (GridView)sender;
    if (grid.SortExpression == e.SortExpression)
    {
        if (grid.SortDirection == SortDirection.Ascending)
        {
            e.SortDirection = SortDirection.Descending;
        }
    }
}

最后,这是我在上面的示例中使用的Reflector课程的代码。

/// <summary>Utility class. Provides static reflection-based utility methods.</summary>
public static class Reflector
{
    #region Public Methods and Operators

    /// <summary>Gets the name of the property that is accessed by the given expression. Usage: <c>Reflector.GetPropertyName&lt;MyClass&gt;(obj =&gt; obj.MyProperty);</c></summary>
    /// <param name="selectorExpression">The expression that selects the property of which the name should be returned.</param>
    /// <typeparam name="T">The type that defines the property.</typeparam>
    /// <returns>The name of the property.</returns>
    public static string GetPropertyName<T>(Expression<Func<T, object>> selectorExpression) where T : class
    {
        MemberExpression memberExpression;
        var unaryExpression = selectorExpression.Body as UnaryExpression;
        if (unaryExpression != null)
        {
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = selectorExpression.Body as MemberExpression;
        }

        if (memberExpression == null)
        {
            return null;
        }

        return memberExpression.Member.Name;
    }

    #endregion
}