silverlight + wcf(json格式) + sqlserver存储过程分页
silverlight并沒有提供現(xiàn)成的分頁控件,百度了一圈,也沒有發(fā)現(xiàn)aspx中好用的類似AspNetPager成熟控件,網(wǎng)上現(xiàn)有的一些分頁代碼,很多也是基于1.0版本的,silverlight2.0的并不多,自個兒琢磨了一下,發(fā)現(xiàn)自己弄一個也并非難事,思路和主要代碼分享如下:
1.通用的“海量”數(shù)據(jù)分頁存儲過程
在做aspx開發(fā)時我已經(jīng)用存儲過程分頁多年,這個東東是通用的(不管前端用什么語言來做),而且性能也不錯,所以這里就直接套過來用了,百度一下"分頁存儲過程"會有N多版本,這里也給出我自己寫的一個版本(僅適用于sqlserver 2005及以上版本)
--?=============================================
--?Author:????????<楊俊明-菩提樹下的楊過>
--?Create?date:?<2006-11-05>
--?Description:????<高效分頁存儲過程,僅適用于Sql2005>
--?Notes:????????<排序字段強烈建議建索引>
--?=============================================
CREATE?Procedure?[dbo].[up_Page2005]?
?@TableName?varchar(500),????????--表名
?@Fields?nvarchar(MAX)?=?'*',????--字段名(全部字段為*)
?@OrderField?nvarchar(MAX),????????--排序字段(必須!支持多字段)
?@sqlWhere?nvarchar(MAX)?=?Null,--條件語句(不用加where)
?@pageSize?int,????????????????????--每頁多少條記錄
?@pageIndex?int?=?1?,????????????--指定當前為第幾頁
?@TotalPage?int?output????????????--返回總頁數(shù)?
as
begin
????Begin?Tran?--開始事務
????Declare?@sql?nvarchar(MAX);
????Declare?@totalRecord?int;????
????--計算總記錄數(shù)
?????????
????if?(@SqlWhere=''?or?@sqlWhere=NULL)
????????set?@sql?=?'select?@totalRecord?=?count(*)?from?'?+?@TableName
????else
????????set?@sql?=?'select?@totalRecord?=?count(*)?from?'?+?@TableName?+?'?where?'?+?@sqlWhere
????
????EXEC?sp_executesql?@sql,N'@totalRecord?int?OUTPUT',@totalRecord?OUTPUT--計算總記錄數(shù)????????
????
????--計算總頁數(shù)
????select?@TotalPage=CEILING((@totalRecord+0.0)/@PageSize)
????if?(@SqlWhere=''?or?@sqlWhere=NULL)
????????set?@sql?=?'Select?*?FROM?(select?ROW_NUMBER()?Over(order?by?'?+?@OrderField?+?')?as?RowId,'?+?@Fields?+?'?from?'?+?@TableName?+?'?with?(nolock)'?
????else
????????set?@sql?=?'Select?*?FROM?(select?ROW_NUMBER()?Over(order?by?'?+?@OrderField?+?')?as?RowId,'?+?@Fields?+?'?from?'?+?@TableName?+?'?with?(nolock)?where?'?+?@SqlWhere????
????????
????
????--處理頁數(shù)超出范圍情況
????if?@PageIndex<=0?
????????Set?@pageIndex?=?1
????
????if?@pageIndex>@TotalPage
????????Set?@pageIndex?=?@TotalPage
?????--處理開始點和結束點
????Declare?@StartRecord?int
????Declare?@EndRecord?int
????
????set?@StartRecord?=?(@pageIndex-1)*@PageSize?+?1
????set?@EndRecord?=?@StartRecord?+?@pageSize?-?1
????--繼續(xù)合成sql語句
????set?@Sql?=?@Sql?+?')?as?'?+?@TableName?+?'?where?RowId?between?'?+?Convert(varchar(50),@StartRecord)?+?'?and?'?+??Convert(varchar(50),@EndRecord)
????print?@sql?;
????Exec(@Sql)
????---------------------------------------------------
????If?@@Error?<>?0
??????Begin
????????RollBack?Tran
????????Return?-1
??????End
????Else
??????Begin
????????Commit?Tran
????????Return?@totalRecord?---返回記錄總數(shù)
??????End
end
??
Code--?=============================================
--?Author:????????<楊俊明-菩提樹下的楊過>
--?Create?date:?<2006-11-05>
--?Description:????<高效分頁存儲過程,僅返回總頁數(shù)和總記錄數(shù),僅適用于Sql2005>
--?Notes:????????<排序字段強烈建議建索引>
--?=============================================
CREATE?Procedure?[dbo].[up_Page2005_Statistic]?
?@TableName?varchar(500),????????--表名
?@Fields?nvarchar(MAX)?=?'*',????--字段名(全部字段為*)
?@OrderField?nvarchar(MAX),????????--排序字段(必須!支持多字段)
?@sqlWhere?nvarchar(MAX)?=?Null,--條件語句(不用加where)
?@pageSize?int,????????????????????--每頁多少條記錄
?@pageIndex?int?=?1?,????????????--指定當前為第幾頁
?@TotalPage?int?output????????????--返回總頁數(shù)?
as
begin???
????Declare?@sql?nvarchar(MAX);
????Declare?@totalRecord?int;????
????--計算總記錄數(shù)?????????
????if?(@SqlWhere=''?or?@sqlWhere=NULL)
????????set?@sql?=?'select?@totalRecord?=?count(*)?from?'?+?@TableName
????else
????????set?@sql?=?'select?@totalRecord?=?count(*)?from?'?+?@TableName?+?'?where?'?+?@sqlWhere????
????EXEC?sp_executesql?@sql,N'@totalRecord?int?OUTPUT',@totalRecord?OUTPUT--計算總記錄數(shù)????????
????
????--計算總頁數(shù)
????select?@TotalPage=CEILING((@totalRecord+0.0)/@PageSize)???
????
????print?'TotalRecord='?+?Convert(nvarchar(50),@totalRecord);
????print?'TotalPage='?+?Convert(nvarchar(50),@totalPage);
????Return?@totalRecord?---返回記錄總數(shù)
end
?
注:第二個是直接在第一個基礎上簡化得來的,僅返回總頁數(shù)和總記錄數(shù);方便某些不需要返回實體數(shù)據(jù),僅需要知道總頁數(shù)和總記錄數(shù)的特殊情況調(diào)用
2.利用wcf直接或間接調(diào)用存儲過程,返回json數(shù)據(jù)
wcf能返回json數(shù)據(jù)已經(jīng)不是什么新鮮事兒了,這里就不多說了,貼出主要代碼(直接拿我以前封裝好的工具庫中的一個方法示例一下,大家知道意思就可以了)?
Code///?<summary>
????????///?調(diào)用分頁存儲過程,返回Json數(shù)據(jù)
????????///?</summary>
????????///?<param?name="pTable"></param>
????????///?<param?name="pWhere"></param>
????????///?<param?name="pFields"></param>
????????///?<param?name="pOrder"></param>
????????///?<param?name="pPageSize"></param>
????????///?<param?name="pPageIndex"></param>
????????///?<param?name="pTotalPage"></param>
????????///?<param?name="pTotalRecord"></param>
????????///?<returns></returns>
????????[WebInvoke(Method?=?"*",?ResponseFormat?=?WebMessageFormat.Json,?UriTemplate?=?"SelectPageData?pTable={pTable}&pWhere={pWhere}&pFields={pFields}&pOrder={pOrder}&pPageSize={pPageSize}&pPageIndex={pPageIndex}&pTotalPage={pTotalPage}&pTotalRecord={pTotalRecord}")]
????????[OperationContract]
????????public?Stream?SelectPageData(string?pTable,?string?pWhere,?string?pFields,?string?pOrder,?int?pPageSize,int?pPageIndex,int?pTotalPage,int?pTotalRecord)
????????{????????????
????????????return?GetStream(GetJsonData(Database.GetDataTableForPage(pTable,pFields,pOrder,pWhere,pPageSize,pPageIndex,pTotalPage,pTotalRecord)));
????????}
????????///?<summary>
????????///?調(diào)用分頁存儲過程,返回總頁數(shù)和總記錄數(shù)
????????///?</summary>
????????///?<param?name="pTable"></param>
????????///?<param?name="pWhere"></param>
????????///?<param?name="pFields"></param>
????????///?<param?name="pOrder"></param>
????????///?<param?name="pPageSize"></param>
????????///?<param?name="pPageIndex"></param>
????????///?<param?name="pTotalPage"></param>
????????///?<param?name="pTotalRecord"></param>
????????///?<returns></returns>
????????[WebInvoke(Method?=?"*",?ResponseFormat?=?WebMessageFormat.Json,?UriTemplate?=?"SelectPageDataStatistic?pTable={pTable}&pWhere={pWhere}&pFields={pFields}&pOrder={pOrder}&pPageSize={pPageSize}&pPageIndex={pPageIndex}&pTotalPage={pTotalPage}&pTotalRecord={pTotalRecord}")]
????????[OperationContract]
????????public?Stream?SelectPageDataStatistic(string?pTable,?string?pWhere,?string?pFields,?string?pOrder,?int?pPageSize,?int?pPageIndex,?int?pTotalPage,?int?pTotalRecord)
????????{
???????????Database.GetTotalPageAndTotalRecordForPage(pTable,?pFields,?pOrder,?pWhere,?pPageSize,?pPageIndex,?out?pTotalPage,out?pTotalRecord);
???????????string?_Result?=?"{'TotalPage':'"?+?pTotalPage.ToString()?+?"','RecordCount':'"?+?pTotalRecord?+?"'}";
???????????return?GetStream(_Result);
????????}
?其中有二個方法GetStream和GetJsonData,主要用于將字符串轉換為流,以及將格式化Json字符串?
Codeprivate?Stream?GetStream(string?str)
????????{
????????????MemoryStream?ms?=?new?MemoryStream();
????????????StreamWriter?sw?=?new?StreamWriter(ms);
????????????sw.AutoFlush?=?true;
????????????sw.Write(str);
????????????ms.Position?=?0;
????????????WebOperationContext.Current.OutgoingResponse.ContentType?=?"text/plain";
????????????return?ms;
????????}
????????public?static?string?GetJsonData(DataTable?dt)
????????{
????????????string?_Result?=?Utils.CreateJsonParameters(dt);//CreateJsonParameters是我工具庫里的一個方法,用于將DataTable轉化為json字符串
????????????if?(_Result.IsNullStr())
????????????{
????????????????_Result?=?"[{}]";
????????????}
????????????else
????????????{
????????????????if?(_Result.StartsWith("{?\"Head\":["))
????????????????{
????????????????????_Result?=?_Result.Replace("{?\"Head\":[",?"[");
????????????????}
????????????????if?(_Result.EndsWith("]}"))?
????????????????{
????????????????????_Result?=?_Result.Trim("}");
????????????????}
????????????}???????????
????????????return?_Result;
????????}
?
3.前面二步弄完了,基本上就可以動手寫silverlight代碼了
xaml前端文件:
Code<UserControl
???
????xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
????xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"??
????x:Class="WcfTest.DataGrid"
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?
????>
???
????<Grid?x:Name="LayoutRoot"?Background="White"?ShowGridLines="False">
????????<Grid.RowDefinitions>
????????????<RowDefinition>????????????????
????????????</RowDefinition>
????????????<RowDefinition?Height="25">
????????????</RowDefinition>
????????</Grid.RowDefinitions>
????????<Grid.ColumnDefinitions>
????????????<ColumnDefinition>
????????????????
????????????</ColumnDefinition>
????????????<ColumnDefinition>
????????????</ColumnDefinition>
????????</Grid.ColumnDefinitions>
????????
????????<data:DataGrid?x:Name="dg"?AutoGenerateColumns="False"?Grid.Column="0"?Grid.Row="0"?Grid.ColumnSpan="2">
????????????<data:DataGrid.Columns>
????????????????<data:DataGridTextColumn?Header="F_ID"
????????????????Binding="{Binding?F_ID}"?/>
????????????????<data:DataGridTextColumn?Header="F_ClassName"?
????????????????Binding="{Binding?F_ClassName}"?/>
????????????????<data:DataGridTextColumn?Header="F_RootId"?
????????????????Binding="{Binding?F_RootId}"?/>
????????????????<data:DataGridTextColumn?Header="F_Depth"?
????????????????Binding="{Binding?F_Depth}"?/>
????????????????<data:DataGridTextColumn?Header="F_Type"?
????????????????Binding="{Binding?F_Type}"?/>
????????????????
????????????</data:DataGrid.Columns>
????????</data:DataGrid>
????????
????????<TextBlock?x:Name="txtStat"?Text="共有X條記錄,第X頁/共X頁,X/每頁"?Grid.Row="1"?Grid.Column="0"?VerticalAlignment="Center"?Margin="5,0,0,0"?></TextBlock>
????????<StackPanel?Grid.Column="1"?Grid.Row="1"?HorizontalAlignment="Right"?Orientation="Horizontal"?VerticalAlignment="Center"?Height="22">
????????????<Button?x:Name="btnFirst"?Content="首頁"?Click="btnFirst_Click"?></Button>
????????????<Button?x:Name="btnPrev"?Content="上頁"?Margin="5,0,0,0"?Click="btnPrev_Click"></Button>
????????????<Button?x:Name="btnNext"?Content="下頁"?Margin="5,0,0,0"?Click="btnNext_Click"></Button>
????????????<Button?x:Name="btnLast"?Content="末頁"?Margin="5,0,0,0"?Click="btnLast_Click"?></Button>
????????????<TextBox?x:Name="txtPageIndex"?Text="1"?Margin="5,0,0,0"?Width="30"?KeyUp="txtPageIndex_KeyUp"></TextBox>
????????????<Button?x:Name="btnPageGo"?Content="Go"?Margin="5,0,5,0"?Click="btnPageGo_Click"></Button>
????????</StackPanel>
????</Grid>
</UserControl>
?
講解一下:用Grid布局,先分上下二行,第一行放一個DataGrid控件(silverlight2新增的控件!),第二行分二列,左列顯示統(tǒng)計信息,右列顯示翻頁按鈕?
后端cs代碼:?
Codeusing?System;
using?System.Collections.Generic;
using?System.Json;
using?System.Net;
using?System.Windows.Controls;
using?System.Windows.Media;
using?JIMMY.TOOLS.Silverlight;
namespace?WcfTest
{
????public?partial?class?DataGrid?:?UserControl
????{
????????protected?string?pTable?=?"",?pWhere?=?"",?pFields?=?"",?pOrderField?=?"",?pBaseUri?=?"http://localhost:7055/Demo.svc/";
????????protected?int?pPageSize?=?10,?pPageIndex?=?1,?pTotalPage?=?0,?pTotalRecord?=?0;
????????public?DataGrid()
????????{
????????????InitializeComponent();
????????????#region?初始化查詢參數(shù)
????????????pTable?=?"T_Class";
????????????//pWhere?=?"F_Type='place'?And?F_Depth=0";
????????????pWhere?=?"";
????????????pFields?=?"F_ID,F_ClassName,F_Depth,F_RootId,F_Type";
????????????pOrderField?=?"F_RootId";????????????
????????????#endregion?
????????????//開始查詢
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?加載分頁數(shù)據(jù)
????????///?</summary>
????????void?LoadData()
????????{
???????????
????????????Uri?serviceUri?=?new?Uri(pBaseUri?+?"SelectPageData?pTable="?+?pTable.UrlEncode()?+?"&pWhere="?+?pWhere.UrlEncode()?+?"&pFields="?+?pFields.UrlEncode()?+?"&pOrder="?+?pOrderField.UrlEncode()?+?"&pPageSize="?+?pPageSize.ToString().UrlEncode()?+?"&pPageIndex="?+?pPageIndex.ToString().UrlEncode()?+?"&pTotalPage="?+?pTotalPage.ToString().UrlEncode()?+?"&pTotalRecord="?+?pTotalRecord.ToString().UrlEncode());
????????????WebClient?downloader?=?new?WebClient();
????????????downloader.OpenReadCompleted?+=?new?OpenReadCompletedEventHandler(LoadDataCompleted);
????????????downloader.OpenReadAsync(serviceUri);
????????????txtStat.Text?=?"數(shù)據(jù)加載中";
????????????txtStat.Foreground?=?new?SolidColorBrush(Color.FromArgb(255,?255,?0,?0));
????????}
????????///?<summary>
????????///?加載分頁數(shù)據(jù)的回調(diào)函數(shù)
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????void?LoadDataCompleted(object?sender,?OpenReadCompletedEventArgs?e)
????????{
????????????if?(e.Error?==?null)
????????????{
????????????????try
????????????????{
????????????????????JsonArray?_Arr?=?(JsonArray)JsonArray.Load(e.Result);
????????????????????List<Data>?_List?=?new?List<Data>();
????????????????????for?(int?i?=?0;?i?<?_Arr.Count;?i++)
????????????????????{
????????????????????????_List.Add(new?Data()?{?F_ClassName?=?_Arr[i]["F_ClassName"],?F_Depth?=?int.Parse(_Arr[i]["F_Depth"]),?F_ID?=?new?Guid(_Arr[i]["F_ID"]),?F_RootId?=?int.Parse(_Arr[i]["F_RootId"]),?F_Type?=?_Arr[i]["F_Type"]?});
????????????????????}
????????????????????dg.ItemsSource?=?_List;
????????????????}
????????????????catch?(Exception?ex)
????????????????{
????????????????}
????????????}
????????????else
????????????{
????????????}
????????}
????????///?<summary>
????????///?加載數(shù)據(jù)的總頁數(shù)/總記錄條數(shù)
????????///?</summary>
????????void?LoadDataStatistic()
????????{
????????????Uri?serviceUri?=?new?Uri(pBaseUri?+?"SelectPageDataStatistic?pTable="?+?pTable.UrlEncode()?+?"&pWhere="?+?pWhere.UrlEncode()?+?"&pFields="?+?pFields.UrlEncode()?+?"&pOrder="?+?pOrderField.UrlEncode()?+?"&pPageSize="?+?pPageSize.ToString().UrlEncode()?+?"&pPageIndex="?+?pPageIndex.ToString().UrlEncode()?+?"&pTotalPage="?+?pTotalPage.ToString().UrlEncode()?+?"&pTotalRecord="?+?pTotalRecord.ToString().UrlEncode());
????????????WebClient?downloader?=?new?WebClient();
????????????downloader.OpenReadCompleted?+=?new?OpenReadCompletedEventHandler(LoadDataStatisticCompleted);
????????????downloader.OpenReadAsync(serviceUri);
????????}
????????///?<summary>
????????///?加載數(shù)據(jù)的總頁數(shù)/總記錄條數(shù)--回調(diào)函數(shù)
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????void?LoadDataStatisticCompleted(object?sender,?OpenReadCompletedEventArgs?e)
????????{
????????????if?(e.Error?==?null)
????????????{
????????????????try
????????????????{
????????????????????JsonValue?_json?=?JsonObject.Load(e.Result);??????????????????
????????????????????pTotalPage?=?int.Parse(_json["TotalPage"]);
????????????????????pTotalRecord?=?int.Parse(_json["RecordCount"]);
????????????????????txtStat.Text?=?"共有"?+?pTotalRecord?+?"條記錄,第"?+?pPageIndex.ToString()?+?"頁/共"?+?pTotalPage?+?"頁,"?+?pPageSize.ToString()?+?"/每頁";
????????????????????txtPageIndex.Text?=?pPageIndex.ToString();
????????????????????txtStat.Foreground?=?new?SolidColorBrush(Color.FromArgb(255,?0,?0,?0));
????????????????}
????????????????catch?(Exception?ex)
????????????????{
????????????????}
????????????}
????????????else
????????????{
????????????}
????????}
????????///?<summary>
????????///?上頁
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?btnPrev_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????pPageIndex?=?pPageIndex?<=?1???1?:?pPageIndex?-?1;
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?下頁
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?btnNext_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????pPageIndex?=?pPageIndex?>=?pTotalPage???pTotalPage?:?pPageIndex?+?1;
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?首頁
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?btnFirst_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????pPageIndex?=?1;
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?末頁
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?btnLast_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????pPageIndex?=?pTotalPage;
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?跳轉到指定頁
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?btnPageGo_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????LoadPageIndexData();
????????}
????????private?void?LoadPageIndexData()?
????????{
????????????int?_currentPageIndex?=?1;
????????????if?(!int.TryParse(txtPageIndex.Text,?out?_currentPageIndex))
????????????{
????????????????txtPageIndex.Text?=?_currentPageIndex.ToString();
????????????}
????????????if?(_currentPageIndex?>=?pTotalPage)
????????????{
????????????????_currentPageIndex?=?pTotalPage;
????????????????txtPageIndex.Text?=?_currentPageIndex.ToString();
????????????}
????????????if?(_currentPageIndex?<=?1)
????????????{
????????????????_currentPageIndex?=?1;
????????????????txtPageIndex.Text?=?_currentPageIndex.ToString();
????????????}
????????????pPageIndex?=?_currentPageIndex;
????????????LoadData();
????????????LoadDataStatistic();
????????}
????????///?<summary>
????????///?輸入頁數(shù)回車后,查詢指定頁數(shù)據(jù)
????????///?</summary>
????????///?<param?name="sender"></param>
????????///?<param?name="e"></param>
????????private?void?txtPageIndex_KeyUp(object?sender,?System.Windows.Input.KeyEventArgs?e)
????????{
????????????if?(e.Key?==?System.Windows.Input.Key.Enter)?
????????????{
????????????????LoadPageIndexData();
????????????}
????????}
????}
????///?<summary>
????///?返回數(shù)據(jù)的類
????///?</summary>
????public?class?Data
????{
????????public?Guid?F_ID?{?get;?set;?}
????????public?string?F_ClassName?{?get;?set;?}
????????public?int?F_RootId?{?get;?set;?}
????????public?int?F_Depth?{?get;?set;?}
????????public?string?F_Type?{?get;?set;?}
????}??
???
}
?
主要思路:
定義一組變量變于保存查詢參數(shù)(包括當前第幾頁,每頁多少條記錄之類),然后利用WebClient訪問wcf,將json數(shù)據(jù)download回來,成功后解析為json對象,再轉化為強類型的List<Data>,最后綁定完事
運行效果圖:
轉載于:https://www.cnblogs.com/yjmyzz/archive/2009/03/02/1401622.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的silverlight + wcf(json格式) + sqlserver存储过程分页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 操作 Word 修改word的高级
- 下一篇: 初识临时表