ASP.NET [GridView からの水平スクロール] は、グリッドに水平スクロールを追加する方法を示しています
問題は、自動生成されたページャーもスクロールすることです。
外部ページャーを作成できますが、より良い解決策はありますか?
問題は、ページャーをスクロール可能にせずに、グリッドビューのみを水平方向にスクロール可能にする簡単な方法があるかどうかです。
ASP.NET [GridView からの水平スクロール] は、グリッドに水平スクロールを追加する方法を示しています
問題は、自動生成されたページャーもスクロールすることです。
外部ページャーを作成できますが、より良い解決策はありますか?
問題は、ページャーをスクロール可能にせずに、グリッドビューのみを水平方向にスクロール可能にする簡単な方法があるかどうかです。
はるかに簡単な別の解決策:
これは私が作成できる最も簡単なものです...うまくいけばそれが役立つでしょう...
<table id="customPager">
</table>
<hr />
<div id="dvGridView" style="height: 200px;overflow:scroll;">
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" PageSize="5">
<PagerSettings Position="Top" />
<PagerStyle CssClass="pagerStyle" />
</asp:GridView>
</div>
<script>
$('#customPager').html($('.pagerStyle').html());
$('.pagerStyle').html('');
</script>
erich007 は非常に興味深い答えを出しました。おそらくそれが進むべき道ですが、テストする時間がありませんでした。
次の方法は私のために働いた:
見積もり:
http://blogs.visoftinc.com/2008/03/19/extending-the-gridview-to-work-with-the-new-datapager-control/
新しい DataPager コントロールで動作するように GridView を拡張する
デイブ・マリーニ | 公開日: 2008 年 3 月 19 日 Technorati タグ: ASP.NET、C#
最近、.NET Framework バージョン 3.5 に含まれる新しい ListView コントロールと DataPager コントロールに関する Scott Mitchell の記事を読みました。これにより、GridView などの他のよく知られたデータ バインド コントロールを適応させて、DataPager コントロールと連携できるようにする方法に興味を持ちました。軽く読んで、GridView コントロールの本質についてかなり熟考した後、私はゲームプランを作成し、準備が整いました。DataPager コントロールと通信できるようにデータ バインドされたコントロールを拡張することはそれほど難しくありませんが、データがコントロールにバインドされる方法を理解していることを前提としています。しかし、GridView に独自のページング コントロールが組み込まれているのに、わざわざこれを行う必要があるでしょうか。まず、ページャーをグリッドから切り離すことができると、かなりクールなことを行うことができます。考えられることの 1 つは、左側のバーに GridView を配置し、メイン ウィンドウのどこかにページング コントロールを配置することです。また、2 つのページャーを持つグリッドを使用することもできます。データのページングにどちらを使用するかに関係なく、それぞれが現在のページを一貫して追跡します。最後に、ページャーのテンプレート コントロールは、GridView 自体のテンプレート コントロールと比較して非常に強力です。
データバインドされたコントロールが DataPager と通信する方法から始めましょう。DataPager コントロールは、System.Web.Extensions アセンブリにある IPageableItemContainer インターフェイスを実装する任意のコントロールに接続できます。以下は、.NET Reflector のおかげで、インターフェイスがどのように見えるかを簡単に示したものです。
public interface IPageableItemContainer
{
//Events
event EventHandler<PageEventArgs> TotalRowCountAvailable;
// Methods
void SetPageProperties(int startRowIndex, int maximumRows, bool databind);
// Properties
int MaximumRows { get; }
int StartRowIndex { get; }
}
インターフェイスの MaximumRows プロパティと StartRowIndex プロパティは、データ バインドされたコントロールが表示するデータ ウィンドウを決定する方法を作成するためのものです。これにより、データの「ページ」と見なされるものの基礎が効果的に定義されます。SetPageProperties メソッドは、DataPager との対話において重要です。これは、DataPagerField コントロールのいずれか (たとえば、[次へ] または [前のボタン]) をクリックするたびに DataPager が呼び出すコントロール内のメソッドであるためです。最後に、インターフェイスは TotalRowCountAvailable というイベントを定義します。このイベントは、コントロールにバインドされているデータ内のレコード数を DataPager に通知します。
それでは、DataPager のフックを使用して GridView の拡張を開始しましょう。GridView の観点から IPageableItemContainer インターフェイスについて考えると、MaximumRows は既存の PageSize プロパティと同等であり、StartRowIndex は既存の PageSize および PageIndex プロパティから計算できることがわかります。また、イベントを宣言し、対応するイベント インボーカーを作成して、イベントを準備します。新しいページング機能をこのグリッドのデフォルトにしたいので、ページが読み込まれるたびに Pager 自体を非表示にします。必要に応じて、この動作にトグルを追加できます。最後に、SetPageProperties メソッドをスタブ化しますが、すぐに再訪するので、ここでは空白のままにします。これまでのところ、新しい GridView は次のようになります。
public class PageableGridView : GridView, IPageableItemContainer
{
public PageableGridView() : base()
{
PagerSettings.Visible = false;
}
public event EventHandler<PageEventArgs> TotalRowCountAvailable;
public int MaximumRows
{
get{ return this.PageSize; }
}
public int StartRowIndex
{
get{ return (this.PageSize * this.PageIndex); }
}
protected virtual void OnTotalRowCountAvailable(PageEventArgs e)
{
if (TotalRowCountAvailable != null)
TotalRowCountAvailable(this, e);
}
protected virtual void SetPageProperties(int startRowIndex, int maximumRows, bool dataBind) { }
}
良いニュースは、半分以上進んだことです。ここで、物事はもう少し複雑になります。ユーザーがボタンの 1 つをクリックしたときに表示する必要があると DataPager が示す内容に基づいて、ページサイズと開始行の値を使用してコントロールを設定する方法がまだ必要です。ここで SetPageProperties メソッドの出番です。仕事を成し遂げる基本的な実装は次のとおりです。
保護された仮想ボイド SetPageProperties(int startRowIndex, int maximumRows, bool dataBind) { if (databind) { PageSize = maximumRows; int newPageIndex = (startRowIndex / PageSize); if (PageIndex != newPageIndex) { OnPageIndexChanging(new GridViewPageEventArgs(newPageIndex)); PageIndex = newPageIndex; OnPageIndexChanged(EventArgs.Empty); } } RequiresDataBinding = データバインド; DataPager がグリッドにページング情報を送信するとき、グリッドは適切なパラメーターを設定して、適切なデータ ウィンドウにバインドする準備を整える必要があります。グリッドがこれを行うために既に装備されている 2 つのプロパティは、PageSize および PageIndex プロパティです。これらのプロパティは、メソッドに送信された情報から計算できます。だから私たちはそれらを設定します。もちろん、ページが変更されている場合は、おそらく OnPageIndexChanging イベントを発生させる必要があります。これは、データソースにバインドしていない場合でも、このイベントを確実に処理する必要があることを意味します。最後に、DataPager がデータにバインド中の場合は、グリッド自体に再バインドするように指示します。これは基本的な実装であるため、ここでもデータ整合性チェックを行う必要があります。たとえば、新しい PageIndex と StartRowIndex の値が有効な範囲内にあることを確認します。
GridView を DataPager に統合するには、あと 1 つだけ行う必要があります。DataPager が適切な数のページ ボタンをレンダリングするために、またはページャーの次または前のページ ボタンをいつ無効にするかを知るために、合計行数を知る必要があります。これは、DataPager 自体で宣言的に指定されるページ サイズと相まって、データ ソースに含まれるページ数を決定するのに役立ちます。問題は、この情報がポケットベルに認識されないことです。ただし、GridView には認識されているため、そこから取得して DataPager に渡す必要があります。しかし、GridView にこのデータがあることを確認できるのはいつでしょうか。GridView コントロールは CompositeDataboundControl から継承します。この型には、コントロールがデータにバインドされているか、単に再レンダリングされているかを示すプロパティも受け取る、CreateChildControls メソッドの特別なバリアントが含まれています。少し考えてみると、GridView がこのメソッドを使用してデータ ソースにバインドしていることがわかります。これを知っていると、TotalRowCountAvailable イベントを発生させるためのトリガーを挿入したい場所がここにあるようです。データソースに手動でバインドする場合、または ObjectDataSource や SqlDataSource などの DataSource コントロールを使用する場合を処理する必要があるため、これは少し複雑になります。これらには合計行数が指定されています。適切な値を取得するには、いくつかのヘルパー メソッドが必要です。少し考えてみると、GridView がこのメソッドを使用してデータ ソースにバインドしていることがわかります。これを知っていると、TotalRowCountAvailable イベントを発生させるためのトリガーを挿入したい場所がここにあるようです。データソースに手動でバインドする場合、または ObjectDataSource や SqlDataSource などの DataSource コントロールを使用する場合を処理する必要があるため、これは少し複雑になります。これらには合計行数が指定されています。適切な値を取得するには、いくつかのヘルパー メソッドが必要です。少し考えてみると、GridView がこのメソッドを使用してデータ ソースにバインドしていることがわかります。これを知っていると、TotalRowCountAvailable イベントを発生させるためのトリガーを挿入したい場所がここにあるようです。データソースに手動でバインドする場合、または ObjectDataSource や SqlDataSource などの DataSource コントロールを使用する場合を処理する必要があるため、これは少し複雑になります。これらには合計行数が指定されています。適切な値を取得するには、いくつかのヘルパー メソッドが必要です。その中に指定された合計行数があります。適切な値を取得するには、いくつかのヘルパー メソッドが必要です。その中に指定された合計行数があります。適切な値を取得するには、いくつかのヘルパー メソッドが必要です。
//Gets row count from SqlDataSource and the like...
private int _GetTotalRowsFromDataSourceObject(IEnumerable dataSource)
{
DataSourceView view = this.GetData(); if (AllowPaging && view.CanPage && view.CanRetrieveTotalRowCount)
return base.SelectArguments.TotalRowCount;
else
return (PageIndex * PageSize) + _GetSourceCount(dataSource);
}
//Gets the row count from a manually bound source or from a source in viewstate
private int _GetSourceCount(IEnumerable dataSource)
{
ICollection source = dataSource as ICollection;
return source != null ?
source.Count :
(from x in dataSource.OfType<object>() select 1).Sum();
}
_GetTotalRowsFromDataSourceObject メソッドは、使用可能な場合、DataSource オブジェクトからレコードの総数を取得します。これは、DataSource コントロールで EnablePaging プロパティが設定されているかどうか、およびオブジェクトがクエリ操作を完了したかどうかなど、いくつかの要因によって異なります。最悪の場合、データの 1 ページを返し、それで完了します。_GetSourceCount メソッドは、2 つの特定の場合に使用されます。まず、グリッドの DataSource プロパティを手動でバインドしてから DataBind() を呼び出すイベントで行数を取得する方法です。第 2 に、このメソッドは、viewstate に格納されているデータへのポストバック後にグリッドが再バインドされている場合にも役立ちます。どちらの場合も、少しの linq を使用して、データソース内の結果のデータ項目 (ビューステートの場合は行) の総数を抽出します。では行こう」
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int baseResult = base.CreateChildControls(dataSource, dataBinding);
if (dataSource != null)
{
int dataSourceCount = (IsBoundUsingDataSourceID && dataBinding) ?
_GetTotalRowsFromDataSource(dataSource) :
_GetSourceCount(dataSource);
OnTotalRowCountAvailable(new PageEventArgs(StartRowIndex, MaximumRows, dataSourceCount));
}
return baseResult;
}
基本コントロールの CreateChildControls メソッドが最初に呼び出されます。これは、グリッドが実際にデータバインディングを行うために使用するためです。バインドするデータがない場合、ページャーに通知する理由がないため、データがあることを確認してから、上記のプロセスを通じてソース内の行数を決定します。最後に、派生データを使用してイベントを発生させ、元の結果に依存する可能性のある他の操作に影響を与えないように、元の結果を返します。これで、新しい DataPager コントロールと結合できる GridView ができました。ページでこれらのコントロールを一緒に使用するために使用するマークアップのサンプルを次に示します。
<asp:DataPager ID="DataPager1" runat="server" PageSize="2" PagedControlID="grid2">
<Fields>
<asp:NextPreviousPagerField />
</Fields>
</asp:DataPager>
<custom:pageablegridview id="grid2" runat="server" autogeneratecolumns="true" allowpaging="true"
onpageindexchanging="grid2_PageIndexChanging" />
DataPager の PageSize プロパティがこの値を制御するため、GridView の PageSize プロパティを指定する必要がないことに注意してください。これを確実にするために、グリッドの PageSize プロパティをシャドウすることができますが、今のところはこれで十分です。それだけです。データにバインドされた新しく作成されたサーバー コントロールの場合、これらの侵入を行って、コントロールが DataPager と連携できるようにするのは非常に簡単です。GridView などの既存のコントロールの場合、バインドがどのように行われるかを把握し、必要な値が存在することがわかっている場所に機能を挿入するだけです。