Skip to main content
deleted 33 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

FewA few days ago, I was looking for simple pagination example and I decided to write my own version. It is one of my first apps using MVVM Pattern, so I am not sure I did right. I would appreciate if you could tell if I did something wrong, or used bad programming practises or whatever.

github.com/Dessembrae/MVVM-ListView-PaginationGitHub

Ok so here we have a MainWindow:MainWindow:

<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

And User Control with buttons for pagination:

<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>
<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

And my ViewModel:User Control with buttons for pagination:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}
<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>

ViewModel:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}

And last snippet is the code for one of the Command classess:One of the Command classes:

namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}
namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}

I'm not a professional programmer, so all my knowledge comes from tutorials. I was trying to mantain a MVVM Pattern and I would like to know if I succeded. And alsosucceeded, as well as any constructive criticism about my skills as a programmer in overall will be appreciated.

Few days ago I was looking for simple pagination example and I decided to write my own version. It is one of my first apps using MVVM Pattern, so I am not sure I did right. I would appreciate if you could tell if I did something wrong, or used bad programming practises or whatever.

github.com/Dessembrae/MVVM-ListView-Pagination

Ok so here we have a MainWindow:

<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

And User Control with buttons for pagination:

<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>

And my ViewModel:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}

And last snippet is the code for one of the Command classess:

namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}

I'm not a professional programmer, so all my knowledge comes from tutorials. I was trying to mantain a MVVM Pattern and I would like to know if I succeded. And also any constructive criticism about my skills as a programmer in overall will be appreciated.

A few days ago, I was looking for simple pagination example and I decided to write my own version. It is one of my first apps using MVVM Pattern, so I am not sure I did right. I would appreciate if you could tell if I did something wrong, or used bad programming practises or whatever.

GitHub

MainWindow:

<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

User Control with buttons for pagination:

<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>

ViewModel:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}

One of the Command classes:

namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}

I'm not a professional programmer, so all my knowledge comes from tutorials. I was trying to mantain a MVVM Pattern and I would like to know if I succeeded, as well as any constructive criticism about my skills as a programmer overall.

code snippets
Source Link
Dess
  • 31
  • 1
  • 1
  • 3

Ok so here we have a MainWindow:

<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

And User Control with buttons for pagination:

<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>

And my ViewModel:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}

And last snippet is the code for one of the Command classess:

namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}

I'm not a professional programmer, so all my knowledge comes from tutorials. I was trying to mantain a MVVM Pattern and I would like to know if I succeded. And also any constructive criticism about my skills as a programmer in overall will be appreciated.

Ok so here we have a MainWindow:

<Window x:Class="MVVMListViewPagination.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:userControls="clr-namespace:MVVMListViewPagination.Views"
    Title="MVVM - ListView Pagination" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListView ItemsSource="{Binding ViewList.View}" Margin="5">
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Id" Width="40" DisplayMemberBinding="{Binding Id}" />
                <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Surname" Width="150" DisplayMemberBinding="{Binding Surname}" />
            </GridView>
        </ListView.View>
    </ListView>
    
    <userControls:PaginationElements Grid.Row="1" Margin="5" />
    
</Grid>

And User Control with buttons for pagination:

<UserControl x:Class="MVVMListViewPagination.Views.PaginationElements"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style TargetType="TextBlock">
        <Setter Property="Margin" Value="5" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="First" Command="{Binding FirstCommand}"/>
    <Button Content="Previous" Command="{Binding PreviousCommand}"/>
    <TextBlock Width="auto" Text="{Binding CurrentPage}"/>
    <TextBlock Text="of"/>
    <TextBlock Width="auto" Text="{Binding TotalPage}"/>
    <Button Content="Next" Command="{Binding NextCommand}"/>
    <Button Content="Last" Command="{Binding LastCommand}"/>
</StackPanel>

And my ViewModel:

namespace MVVMListViewPagination.ViewModels
{
    class MainViewModel : BaseViewModel
    {
        #region Commands
        public ICommand PreviousCommand { get; private set; }
        public ICommand NextCommand { get; private set; }
        public ICommand FirstCommand { get; private set; }
        public ICommand LastCommand { get; private set; }
        #endregion

        #region Fields And Properties
        int itemPerPage = 15;
        int itemcount;
        private int _currentPageIndex;
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set { _currentPageIndex = value; OnPropertyChanged("CurrentPage"); }
        }
        public int CurrentPage
        {
            get { return _currentPageIndex + 1; }
        }

        private int _totalPage;
        public int TotalPage
        {
            get { return _totalPage; }
            set { _totalPage = value; OnPropertyChanged("TotalPage"); }
        }

        public CollectionViewSource ViewList { get; set; }
        public ObservableCollection<Person> peopleList = new ObservableCollection<Person>();
        #endregion

        #region Pagination Methods
        public void ShowNextPage()
        {
            CurrentPageIndex++;
            ViewList.View.Refresh();
        }

        public void ShowPreviousPage()
        {
            CurrentPageIndex--;
            ViewList.View.Refresh();
        }

        public void ShowFirstPage()
        {
            CurrentPageIndex = 0;
            ViewList.View.Refresh();
        }

        public void ShowLastPage()
        {
            CurrentPageIndex = TotalPage - 1;
            ViewList.View.Refresh();
        }

        void view_Filter(object sender, FilterEventArgs e)
        {
            int index = ((Person)e.Item).Id - 1;
            if (index >= itemPerPage * CurrentPageIndex && index < itemPerPage * (CurrentPageIndex + 1))
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }

        private void CalculateTotalPages()
        {
            TotalPage = (itemcount / itemPerPage);
            if (itemcount % itemPerPage != 0)
            {
                TotalPage += 1;
            }
        }
        #endregion

        public MainViewModel()
        {
            populateList();

            ViewList = new CollectionViewSource();
            ViewList.Source = peopleList;
            ViewList.Filter += new FilterEventHandler(view_Filter);

            CurrentPageIndex = 0;
            itemcount = peopleList.Count;
            CalculateTotalPages();

            NextCommand = new NextPageCommand(this);
            PreviousCommand = new PreviousPageCommand(this);
            FirstCommand = new FirstPageCommand(this);
            LastCommand = new LastPageCommand(this);
        }

        private void populateList()
        {
            for (int i = 0; i < 100; i++)
            {
                peopleList.Add(new Person(i, "Jack", "Black"));
            }
        }
    }
}

And last snippet is the code for one of the Command classess:

namespace MVVMListViewPagination.Commands
{
    class FirstPageCommand : ICommand
    {
        private MainViewModel viewModel;

        public FirstPageCommand(MainViewModel viewModel)
        {
            this.viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            if (viewModel.CurrentPageIndex == 0)
                return false;
            else
                return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            viewModel.ShowFirstPage();
        }
    }
}

I'm not a professional programmer, so all my knowledge comes from tutorials. I was trying to mantain a MVVM Pattern and I would like to know if I succeded. And also any constructive criticism about my skills as a programmer in overall will be appreciated.

Source Link
Dess
  • 31
  • 1
  • 1
  • 3
Loading