DataContext / DataGrid创建重复的行

时间:2016-05-22 07:59:06

标签: c# wpf datatable pagination datacontext

我一直在捣乱我的大脑几个小时试图找出导致这种情况的原因。我有一个Access数据库,用于在C#/ WPF中提供DataGrid。我正在使用一个DataTable提供给一个自定义类,用于Paginating一个CollectionView,它引入一个绑定到DataGrid的DataContext。我已经从程序启动到绘制DataGrid一直跟踪这一点,并且始终存在正确的行数(使用MessageBox.Show(CollectionView.Count.ToString())来验证它)。即使在绘制DataGrid之后,也有正确数量的项目(200),所以我认为它必须是DataGrid在通过Pagination类运行后显示项目的方式,但我似乎找不到任何地方问题可能源于。有人可以看看这段代码,看看他们是否注意到任何可能导致这种情况发生的事情吗?

关于重复项显示的几个注释:如果我在方法调用中更改itemsPerPage值,它会影响重复项的分隔方式。如果每页200个,则组中有8个重复项。每页100个导致一行的4个重复,然后是4个另一个,然后是第一个中的4个。像这样:

  • 200 itemsPerPage:aaaaaaa bbbbbbbb cccccccc dddddddd
  • 100 itemsPerPage:aaaa bbbb aaaa bbbb cccc dddd cccc dddd

显然这些是行,所以它们向下而不是向左,但概念应该是明确的。

更新:我以前忘了提及,但是分页课是基于这个问题的答案: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();
    }
}

1 个答案:

答案 0 :(得分:0)

所以看起来这个问题只是一个错误的简单案例。当我更新要反映的问题时,我在前一个问题中找到了Paging类。显然,当我将它复制到Visual Studio中时,我混合了两种方法,这在某种程度上导致了这个问题。为了将来的参考,我发布了下面的相关方法。

    public int PageCount
    {
        get
        {
            return (this._innerList.Count + this._itemsPerPage - 1) / this._itemsPerPage;
        }
    }

    public int EndIndex
    {
        get
        {
            int end = this._currentPage * this._itemsPerPage - 1;
            return (end > this._innerList.Count) ? this._innerList.Count : end;
        }
    }

我已将EndIndex方法的内容放在PageCount方法内,并完全退出EndIndex方法。