4

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 を配置すると、インテリセンスのオートコンプリートが提供されませんでした。DataField 属性の文字列しか入力できませんでした。そのようです:

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

おっとっと!「JobTitle」のスペルを間違えたようですが、コンパイラはそれをキャッチしませんでした。したがって、強力な型付けの恩恵を受けるために、必要かどうかに関係なく、すべての列に対して TemplateField オプションを使用することを余儀なくされているようです。

さらに、SortExpression 属性を TemplateField に配置したい場合は、そのスペルも正しいことを期待する必要があります。これは素晴らしい新機能であるため、明らかな何かが欠けていることを願っていますが、半分しか実装されていないようです.

これが本当かどうか、誰かが確認できますか...または何かが足りないのですか?

4

2 に答える 2

1

比較的新しい ASP.NET 開発者として、私はおそらくこの質問に対する完全な答えを知る洞察力や経験を持っていませんが、この問題について最善の理解を示します。私も ASP.net 4.5 の「強く型付けされたモデル バインディング」を使用しました。Scott Hanselman の優れたビデオを介して初めてそれを発見したとき、それは私の心を吹き飛ばしました。あなたが言及した問題は、間違いなく機能の残念な制限です. しかし、私たちが得た助けに感謝すべきだと思います。

ページ内の他の作業を検討して.aspxください。Intellisense は、コントロール属性 (例: の true/false ドロップダウンVisible=) を埋めるためのヘルプを提供しますが、宣言型マークアップの検証は、全体として非常に最小限です。これはまさにその性質の一部です。これは「プログラミング」ドキュメントではなく、セマンティック ドキュメントです。この事実により、プロジェクトを再コンパイルせずに変更できるため、非常に便利な場合があります。

ASP.NET は、インライン コード セクション (<%# %> など) を介して、実際のコンパイル済みコードを aspx マークアップに配置する方法を提供します。厳密に型指定されたバインディングは、これらを利用します。それらはプログラミングの世界への裏口のようなものであり、完全な Intellisense エクスペリエンスを提供します。

いつの日か、この属性に強い型付けが見られる日が来ると予想していDataFieldますが、すぐに探すつもりはありません。今のところ、私はItemType可能な限りいつでもその便利さを利用して喜んでいます.

于 2013-02-07T02:38:30.637 に答える
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 つは、前に定義した並べ替え式 ("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
}
于 2014-10-15T09:20:23.123 に答える