【发布时间】:2016-09-19 04:57:37
【问题描述】:
几个小时以来,我一直在绞尽脑汁想弄清楚是什么原因造成的。我有一个 Access 数据库,它在 C#/WPF 中提供一个 DataGrid。我正在使用一个 DataTable 馈送到自定义类中对 CollectionView 进行分页,该类馈送到绑定到 DataGrid 的 DataContext 中。从程序启动到 DataGrid 的绘制,我一直跟踪这一点,并且始终存在正确的行数(使用 MessageBox.Show(CollectionView.Count.ToString()) 来验证它)。即使在绘制 DataGrid 之后也有正确数量的项目(200),所以我认为这一定是 DataGrid 在通过 Pagination 类运行它们后如何显示项目的问题,但我似乎找不到任何地方问题可能源于。有人可以看看这段代码,看看他们是否注意到任何可能导致这种情况的东西?
关于显示重复项的几点说明:如果我在方法调用中更改 itemsPerPage 值,它会影响重复项的分离方式。如果是每页 200 个,则一组中有 8 个重复项。每页 100 个导致一行 4 个重复,然后是另一个 4 个,然后是第一个重复 4 个。像这样:
- 200 itemsPerPage: aaaaaaaa bbbbbbbb cccccccc dddddddd
- 100 itemsPerPage: aaaa bbbb aaaa bbbb cccc dddd cccc dddd
显然这些是行,所以它们向下而不是向左,但这个概念应该很清楚。
更新:我之前忘了提,但 Pagination 类是基于对这个问题的回答:How can I paginate a WPF DataGrid?
DataGrid XAML:
<DataGrid x:Name="instrumentIdDataGrid" ColumnWidth="Auto" ColumnHeaderStyle="{StaticResource datagridCenterHeaderStyle}" CellStyle="{StaticResource datagridCenterCellStyle}"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="5,5,5,5" AutoGenerateColumns="False" Padding="10"
AutoGeneratingColumn="instrumentIdDataGrid_AutoGeneratingColumn" ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTextColumn Header="Agent TID" Binding="{Binding AgentTID}" />
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
<DataGridTextColumn Header="Team" Binding="{Binding Team}" />
<DataGridTextColumn Header="Instrument ID" Binding="{Binding InstrumentID}" />
<DataGridTextColumn Header="On-Dialer" Binding="{Binding OnDialerExtension}" />
<DataGridTextColumn Header="Off-Dialer" Binding="{Binding OffDialerExtension}" />
</DataGrid.Columns>
</DataGrid>
DataTable 加载方法:(目前只有instruments DataGrid 使用分页,dialerRecords 没有,也可以。)
private void InitializeDataTables()
{
FillDataTable(dialerRecords, @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + backendFilePath + ";User Id=;Password=;", "SELECT * FROM DialerRecords");
FillDataTable(instruments, @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + backendFilePath + ";User Id=;Password=;", "SELECT * FROM InstrumentIDs");
this.instrumentCollectionView = new PagingCollectionView(instruments.DefaultView, 20);
instrumentIdDataGrid.DataContext = instrumentCollectionView;
dialerRecordsDataGrid.DataContext = dialerRecords.DefaultView;
}
private void FillDataTable(System.Data.DataTable table, string connectionString, string queryString)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
using (OleDbDataAdapter adapter = new OleDbDataAdapter(queryString, connection))
{
adapter.Fill(table);
}
}
}
分页类
public class PagingCollectionView : ListCollectionView
{
private readonly IList _innerList;
private readonly int _itemsPerPage;
private int _currentPage = 1;
public PagingCollectionView(IList innerList, int itemsPerPage) : base(innerList)
{
this._innerList = innerList;
this._itemsPerPage = itemsPerPage;
}
public override int Count
{
get
{
if (this._innerList.Count == 0)
return 0;
if(this._currentPage < this.PageCount)
{
return this._itemsPerPage;
}
else
{
int itemsLeft = this._innerList.Count % this._itemsPerPage;
if (0 == itemsLeft)
{
return this._itemsPerPage;
}
else
{
return itemsLeft;
}
}
}
}
public int CurrentPage
{
get { return this._currentPage; }
set
{
this._currentPage = value;
this.OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage"));
}
}
public int ItemsPerPage
{
get
{
return this._itemsPerPage;
}
}
public int PageCount
{
get
{
int end = this._currentPage * this._itemsPerPage - 1;
return (end > this._innerList.Count) ? this._innerList.Count : end;
}
}
private int StartIndex
{
get
{
return (this._currentPage - 1) * this._itemsPerPage;
}
}
public override object GetItemAt(int index)
{
int offset = index & (this._itemsPerPage);
return this._innerList[this.StartIndex + offset];
}
public void MoveToNextPage()
{
if (this._currentPage < this.PageCount)
{
this.CurrentPage += 1;
}
this.Refresh();
}
public void MoveToPreviousPage()
{
if(this._currentPage > 1)
{
this.CurrentPage -= 1;
}
this.Refresh();
}
}
【问题讨论】:
-
先试试这个看看会发生什么。摆脱这个标记 AutoGeneratingColumn="instrumentIdDataGrid_AutoGeneratingColumn"
-
删除标记导致同样的问题,没有变化。我确实怀疑这可能是问题所在,因此我将
AutoGenerateColumns更改为False而之前它是真的。我当时并不积极,但我认为更改为False会阻止事件触发。很高兴知道情况确实如此,我仍然很感激这个建议! :) -
好,试试这个,摆脱分页,直接绑定到仪器集合视图的内容。
-
这实际上是我最初所拥有的,在添加 Paging 类之前(我以为我已经把它放在原始问题中但一定忘记了)。在分页类之前,它工作得很好,没有重复。添加分页类的唯一原因是因为使 DataGrid 成为焦点时的加载时间非常长,大约为 90-120 秒。我尝试了几种方法来减少它,但没有任何效果,所以我搜索并找到了分页类。基于此,我确定问题一定出在分页类中,但我不知道是什么原因造成的。
-
好的,我刚刚发现了问题。我回去仔细检查了原始问题的代码,发现我在 Paging 类中混合了两种方法,并在另一种方法中输入了错误的运算符。基本上我合并了
EndIndex和PageCount方法。无论如何,感谢您的帮助,我真的很感激,它让我回顾了代码并进行了比较,从而找到了问题。 :)
标签: c# wpf datatable pagination datacontext