使用 DataPager 扩展 asp:Repeater 时出现问题
我正在扩展 asp:Repeater 以使用 DataPager,现在我的代码可以使用 SqlDataSource。为了获得更好的性能,我想使用ObjectDataSource,但我必须使用DataPager的QueryStringField,否则我必须单击页码两次才能使其工作。任何人都可以帮忙解决这个问题吗?这是我的代码:
namespace WebTest.UserControl
{
public class PageableRepeater : Repeater, IPageableItemContainer
{
private static readonly object EventTotalRowCountAvailable = new object();
private int _startRowIndex = 0;
private int _maximumRows = -1;
private int _totalRowCount = -1;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override void LoadControlState(object savedState)
{
_startRowIndex = 0;
_maximumRows = -1;
_totalRowCount = -1;
object[] state = savedState as object[];
if (state != null)
{
base.LoadControlState(state[0]);
if (state[1] != null)
{
_totalRowCount = (int)state[1];
}
}
else
{
base.LoadControlState(null);
}
if (!IsViewStateEnabled)
{
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
}
protected override object SaveControlState()
{
object baseState = base.SaveControlState();
if (baseState != null || _totalRowCount != -1)
{
object[] state = new object[2];
state[0] = baseState;
state[1] = _totalRowCount;
return state;
}
return true;
}
protected override System.Collections.IEnumerable GetData()
{
ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource();
pagedDataSource.StartRowIndex = _startRowIndex;
pagedDataSource.MaximumRows = _maximumRows;
if (DataSource is ObjectDataSource)
{
SelectArguments.StartRowIndex = _startRowIndex;
SelectArguments.MaximumRows = _maximumRows;
SelectArguments.RetrieveTotalRowCount = true;
pagedDataSource.DataSource = base.GetData();
_totalRowCount = SelectArguments.TotalRowCount;
pagedDataSource.AllowServerPaging = true;
pagedDataSource.TotalRowCount = _totalRowCount;
}
else
{
pagedDataSource.DataSource = base.GetData();
pagedDataSource.AllowServerPaging = false;
pagedDataSource.TotalRowCount = 0;
_totalRowCount = pagedDataSource.DataSourceCount;
}
return pagedDataSource;
}
protected override void CreateControlHierarchy(bool useDataSource)
{
base.CreateControlHierarchy(useDataSource);
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
private void OnTotalRowCountAvailable(PageEventArgs pageEventArgs)
{
EventHandler<PageEventArgs> handler = (EventHandler<PageEventArgs>)Events[EventTotalRowCountAvailable];
if (handler != null)
{
handler(this, pageEventArgs);
}
}
public int MaximumRows
{
get { return _maximumRows; }
}
public int StartRowIndex
{
get { return _startRowIndex; }
}
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
if (maximumRows < 1)
{
throw new ArgumentOutOfRangeException("maximumRows");
}
if (startRowIndex < 0)
{
throw new ArgumentOutOfRangeException("startRowIndex");
}
_startRowIndex = startRowIndex;
_maximumRows = maximumRows;
if (databind)
{
RequiresDataBinding = true;
}
}
public event EventHandler<PageEventArgs> TotalRowCountAvailable
{
add
{
Events.AddHandler(EventTotalRowCountAvailable, value);
}
remove
{
Events.RemoveHandler(EventTotalRowCountAvailable, value);
}
}
}
}
顺便说一句,我在 CodeProject,但我不认为它很好地使用了 IPageableItemContainer。
I'm extending asp:Repeater to use DataPager, and now my code work with SqlDataSource. To get better performance, I want to use ObjectDataSource with it, but I have to use QueryStringField of DataPager, otherwise I have to click page number twice to make it work. Can any one help on this? this is my code:
namespace WebTest.UserControl
{
public class PageableRepeater : Repeater, IPageableItemContainer
{
private static readonly object EventTotalRowCountAvailable = new object();
private int _startRowIndex = 0;
private int _maximumRows = -1;
private int _totalRowCount = -1;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override void LoadControlState(object savedState)
{
_startRowIndex = 0;
_maximumRows = -1;
_totalRowCount = -1;
object[] state = savedState as object[];
if (state != null)
{
base.LoadControlState(state[0]);
if (state[1] != null)
{
_totalRowCount = (int)state[1];
}
}
else
{
base.LoadControlState(null);
}
if (!IsViewStateEnabled)
{
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
}
protected override object SaveControlState()
{
object baseState = base.SaveControlState();
if (baseState != null || _totalRowCount != -1)
{
object[] state = new object[2];
state[0] = baseState;
state[1] = _totalRowCount;
return state;
}
return true;
}
protected override System.Collections.IEnumerable GetData()
{
ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource();
pagedDataSource.StartRowIndex = _startRowIndex;
pagedDataSource.MaximumRows = _maximumRows;
if (DataSource is ObjectDataSource)
{
SelectArguments.StartRowIndex = _startRowIndex;
SelectArguments.MaximumRows = _maximumRows;
SelectArguments.RetrieveTotalRowCount = true;
pagedDataSource.DataSource = base.GetData();
_totalRowCount = SelectArguments.TotalRowCount;
pagedDataSource.AllowServerPaging = true;
pagedDataSource.TotalRowCount = _totalRowCount;
}
else
{
pagedDataSource.DataSource = base.GetData();
pagedDataSource.AllowServerPaging = false;
pagedDataSource.TotalRowCount = 0;
_totalRowCount = pagedDataSource.DataSourceCount;
}
return pagedDataSource;
}
protected override void CreateControlHierarchy(bool useDataSource)
{
base.CreateControlHierarchy(useDataSource);
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
private void OnTotalRowCountAvailable(PageEventArgs pageEventArgs)
{
EventHandler<PageEventArgs> handler = (EventHandler<PageEventArgs>)Events[EventTotalRowCountAvailable];
if (handler != null)
{
handler(this, pageEventArgs);
}
}
public int MaximumRows
{
get { return _maximumRows; }
}
public int StartRowIndex
{
get { return _startRowIndex; }
}
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
if (maximumRows < 1)
{
throw new ArgumentOutOfRangeException("maximumRows");
}
if (startRowIndex < 0)
{
throw new ArgumentOutOfRangeException("startRowIndex");
}
_startRowIndex = startRowIndex;
_maximumRows = maximumRows;
if (databind)
{
RequiresDataBinding = true;
}
}
public event EventHandler<PageEventArgs> TotalRowCountAvailable
{
add
{
Events.AddHandler(EventTotalRowCountAvailable, value);
}
remove
{
Events.RemoveHandler(EventTotalRowCountAvailable, value);
}
}
}
}
By the way, I found another implementation to this on CodeProject, but I don't think it use IPageableItemContainer very well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这是一个旧的问题,但我最近一直在寻找一种将 Repeater 与 DataPager 控件一起使用的解决方案。
大多数研究将我带到这个 CodeProject 文章,但对我来说似乎有点像黑客。我对这个问题做了一些研究,并在我旋转轮子的时候把它放在一边一段时间,直到我看到你的问题和示例代码。我能够获取您的代码并将其应用到我的代码中以获得可行的解决方案(至少它对我有用)。通过下面的 DataPagerRepeater 控件,我可以将 DataPagerRepeater、DataPager 和数据源(ObjectDataSource 等)拖放到页面上。将 DataPagerRepeaters DataSource 或 DataSourceID 设置为指向数据源,然后将 DataPagers PagedControlID 设置为 DataPagerRepeater。看起来效果很好。
I know this is an old one, but I've recently been looking for a solution to using the Repeater with a DataPager control.
Most research takes me to this CodeProject article, but it seems like a bit of a hack to me. I've worked on this problem a bit, and put it to the side for a while as I was spinning my wheels on it, until I saw your question and sample code. I was able to take your code and apply it to mine to get a working solution (at least it works for me). With the DataPagerRepeater control below, I'm able to drop the DataPagerRepeater, DataPager, and a DataSource (ObjectDataSource, etc) on the page. Set the DataPagerRepeaters DataSource or DataSourceID to point to the data source, then set the DataPagers PagedControlID to the DataPagerRepeater. Seems to work great.