WPF可编辑DataGrid使用分页CollectionView [英] WPF Editable DataGrid using a Paged CollectionView

查看:157
本文介绍了WPF可编辑DataGrid使用分页CollectionView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在执行此帖中提出的分页数据网格)。

 < Window x:Class =WpfApplication1.MainWindow
xmlns =http://schemas.microsoft .com / winfx / 2006 / xaml / presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
xmlns:vm =clr-namespace:WpfApplication1 .ViewModels
Title =MainWindowHeight =350Width =500>

< Window.DataContext>
< vm:CustomersViewModel />
< /Window.DataContext>
< Grid>
< Grid.RowDefinitions>
< RowDefinition Height =Auto/>
< RowDefinition Height =*/>
< /Grid.RowDefinitions>
& DockPanel Grid.Row =0>
< Button Content =PreviousCommand ={Binding MovePreviousCommand}Margin =2/>
< Button Content =NextCommand ={Binding MoveNextCommand}Margin =2/>
< TextBlock Grid.Row =0Margin =2VerticalAlignment =中心Horizo​​ntalAlignment =RightDockPanel.Dock =Right>
< TextBlock.Text>
< MultiBinding StringFormat =Page {0} / {1}>
< Binding Path =PageNumber/>
< Binding Path =TotalPages/>
< / MultiBinding>
< /TextBlock.Text>
< / TextBlock>
< / DockPanel>
< DataGrid ItemsSource ={Binding CustomerCollection}Grid.Row =1>
< DataGrid.Columns>
< DataGridTemplateColumn标题=活动>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
< CheckBox IsChecked ={Binding Path = IsActive,UpdateSourceTrigger = PropertyChanged}/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< DataGridTextColumn Header =First NameWidth =*Binding ={Binding FirstName}/>
< DataGridTextColumn Header =Last NameWidth =*Binding ={Binding LastName}/>
< /DataGrid.Columns>
< / DataGrid>
< / Grid>
< / Window>

版本管理似乎有一个小问题(不停止代码工作)所以您可能想在 PagedCollectionView.MoveNext 中的前四行发表评论。

  public bool MoveNext()
{
// if(this._timestamp!= this._collectionView.Timestamp)
// {
// throw new InvalidOperationException(PagedCollectionViewResources。 EnumeratorVersionChanged);
//}

开关(this._position)


I am implementing a paged datagrid as proposed in this post Pagination in WPF. All works fine, but I have some checkboxes in my grid and when I try to check them, the application throws an exception because CollectionView does not allow the editing. How can I get the list of items in the current view and convert them to a list collection? I've added the following method in the public class PagingCollectionView : CollectionView class for testing:

    private void RefreshGrid()
    {
        //this._currentDataGrid.DataContext = this;   **throws exception** when clicking on 
        //this.Refresh();                             **checkbox

        List<Customer> list = this.Cast<Customer>().ToList();  //** still get the original list
        this._currentDataGrid.DataContext = list;
        this.Refresh();

        //I also tried this
        //this.Refresh();
        //List<Customer> list = this.Cast<Customer>().ToList();  //** same result
        //this._currentDataGrid.DataContext = list;
    }

Ideally I would like to just get what items the view has, at this point I am setting the items per page to 5 but I am getting all 16 of them. The PagingCollectionView works fine except that I can not check the boxes.

解决方案

The PagingCollectionView from your linked post does not implement IEditableCollectionView, and so you are not able to change values in the grid.

Unfortunately, there does not seem to exist a standard paged collection view in WPF. But the PagedCollectionView for Silverlight does work, it's possible to just copy that code into your project. I suppose you could also install Silverlight SDK and add a reference to System.Windows.Data.dll. Or if you can implement IEditableCollectionView yourself, I'm sure you'd find a few takers ;).

For what looks like your best bet, you'll need all code from this page.

Test output:

ViewModel:

using System;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.Windows.Input;

namespace WpfApplication1.ViewModels
{
    public class CustomersViewModel : NotifyBase // replace NotifyBase by implementing INotifyPropertyChanged
    {
        public PagedCollectionView CustomerCollection { get; private set; }
        public int TotalPages { get { return (int)Math.Ceiling((double)CustomerCollection.ItemCount / (double)CustomerCollection.PageSize); } }
        public int PageNumber { get { return CustomerCollection.PageIndex + 1; } } 

        public ICommand MoveNextCommand { get { return GetValue(() => MoveNextCommand); } set { SetValue(() => MoveNextCommand, value); } }
        public ICommand MovePreviousCommand { get { return GetValue(() => MovePreviousCommand); } set { SetValue(() => MovePreviousCommand, value); } }

        public CustomersViewModel()
        {
            this.CustomerCollection = new PagedCollectionView(new ObservableCollection<Customer>
            {
                new Customer(true, "Michael", "Delaney"),
                new Customer(false, "James", "Ferguson"),
                new Customer(false, "Andrew", "McDonnell"),
                new Customer(true, "Sammie", "Hunnery"),
                new Customer(true, "Olivia", "Tirolio"),
                new Customer(false, "Fran", "Rockwell"),
                new Customer(false, "Andrew", "Renard"),
            });
            this.CustomerCollection.PageSize = 3;

            this.MoveNextCommand = new ActionCommand(MoveNext);
            this.MovePreviousCommand = new ActionCommand(MovePrevious);

        }

        private void MoveNext()
        {
            this.CustomerCollection.MoveToNextPage();
            OnPropertyChanged("PageNumber");
        }

        private void MovePrevious()
        {
            this.CustomerCollection.MoveToPreviousPage();
            OnPropertyChanged("PageNumber");
        }
    }

    public class Customer : NotifyBase // replace NotifyBase by implementing INotifyPropertyChanged
    {
        public bool IsActive { get { return GetValue(() => IsActive); } set { SetValue(() => IsActive, value); } }
        public string FirstName { get { return GetValue(() => FirstName); } set { SetValue(() => FirstName, value); } }
        public string LastName { get { return GetValue(() => LastName); } set { SetValue(() => LastName, value); } }

        public Customer(bool isActive, string firstName, string lastName)
        {
            this.IsActive = isActive;
            this.FirstName = firstName;
            this.LastName = lastName;
        }
    }

    public class ActionCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        private Action _action;

        public ActionCommand(Action action)
        {
            _action = action;
        }

        public bool CanExecute(object parameter) { return true; }

        public void Execute(object parameter)
        {
            if (_action != null)
                _action();
        }
    }
}

Xaml (note the TemplateColumn instead of CheckBoxColumn, because of this).

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfApplication1.ViewModels"            
        Title="MainWindow" Height="350" Width="500">

    <Window.DataContext>
        <vm:CustomersViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="0">
            <Button Content="Previous" Command="{Binding MovePreviousCommand}" Margin="2"/>
            <Button Content="Next" Command="{Binding MoveNextCommand}" Margin="2"/>
            <TextBlock Grid.Row="0" Margin="2" VerticalAlignment="Center" HorizontalAlignment="Right" DockPanel.Dock="Right">
                <TextBlock.Text>
                    <MultiBinding StringFormat="Page {0}/{1}">
                        <Binding Path="PageNumber" />
                        <Binding Path="TotalPages" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DockPanel>
        <DataGrid ItemsSource="{Binding CustomerCollection}" Grid.Row="1">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Active">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=IsActive, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="First Name" Width="*" Binding="{Binding FirstName}"/>
                <DataGridTextColumn Header="Last Name" Width="*" Binding="{Binding LastName}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

There seems to be a slight problem with version management (doesn't stop the code from working), so you might want to comment the first four lines in PagedCollectionView.MoveNext.

public bool MoveNext()
{
    //if (this._timestamp != this._collectionView.Timestamp)
    //{
    //    throw new InvalidOperationException(PagedCollectionViewResources.EnumeratorVersionChanged);
    //}

    switch (this._position)

这篇关于WPF可编辑DataGrid使用分页CollectionView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆