آموزش DataGrid در WPF به همراه صفحه بندي و جستجوي انتخابی. کلیک کن www.papro-co.ir



Similar documents
Election 2012: Real- Time Monitoring of Election Results

WINDOWS PRESENTATION FOUNDATION LEKTION 3

Implementing multi-user multi-touch scenarios using WPF in Windows* 8 Desktop Apps

STEP BY STEP to Build the Application 1. Start a. Open a MvvmLight (WPF4) application and name it MvvmControlChange.

An Introduction to the Windows Presentation Foundation with the Model-View-ViewModel

Microsoft Silverlight 5: Building Rich Enterprise Dashboards Todd Snyder, Joel Eden, Ph.D. Jeff Smith, Matthew Duffield

Hands-On Lab. Building a Data-Driven Master/Detail Business Form using Visual Studio Lab version: Last updated: 12/10/2010.

Microsoft Virtual Labs. Building Windows Presentation Foundation Applications - C# - Part 1

Introduction to the BackgroundWorker Component in WPF

Relationships in WPF Applications

Visual COBOL ASP.NET Shopping Cart Demonstration

Paging, sorting, and searching using EF Code first and MVC 3. Introduction. Installing AdventureWorksLT database. Creating the MVC 3 web application

Windows Presentation Foundation (WPF) User Interfaces

Microsoft Windows Apps Dev w/microsoft.net Framework 4.

Chapter 14 WCF Client WPF Implementation. Screen Layout

Introduction to C#, Visual Studio and Windows Presentation Foundation

The full setup includes the server itself, the server control panel, Firebird Database Server, and three sample applications with source code.

WPF Viewer for Reporting Services 2008/2012 Getting Started

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer. Windows 10 Apps Development

Windows Presentation Foundation Tutorial 1

Telerik WPF Controls Tutorial

ADP Workforce Now V3.0

Performance and Usability Improvements for Massive Data Grids using Silverlight

Synchronizing databases

Tutorial 3. Maintaining and Querying a Database

Microsoft Office 2010

When a variable is assigned as a Process Initialization variable its value is provided at the beginning of the process.

wpf5concat Start Microsoft Visual Studio. File New Project WPF Application, Name= wpf5concat OK.

Ad Hoc Report Query Step-by-Step

2012 Teklynx Newco SAS, All rights reserved.

Async startup WPF Application

1. WPF Tutorial Page 1 of 431 wpf-tutorial.com

Bitrix Site Manager 4.1. User Guide

Visual Studio 2008: Windows Presentation Foundation

A Step by Step Guide for Building an Ozeki VoIP SIP Softphone

ADF Code Corner. 66. How-to color-highlight the bar in a graph that represents the current row in the collection. Abstract: twitter.

Introduction to Unit Testing ---

Introduction to Building Windows Store Apps with Windows Azure Mobile Services

Sample- for evaluation purposes only. Advanced Crystal Reports. TeachUcomp, Inc.

Data Binding with WPF: Binding to XML

MyOra 3.0. User Guide. SQL Tool for Oracle. Jayam Systems, LLC

VISION FINANCIALS. Budget Status (GLS8020) Introduction. Purpose of the Report

Windows Presentation Foundation

Xamarin Cross-platform Application Development

Windows Presentation Foundation (WPF)

2Creating Reports: Basic Techniques. Chapter

ASP.NET Dynamic Data

THE USE OF WPF FOR DEVELOPMENT OF INTERACTIVE GEOMETRY SOFTWARE

Designing Reports in Access

Bitrix Site Manager 4.0. Quick Start Guide to Newsletters and Subscriptions

Using Windows Azure Mobile Services to Cloud-Enable your Windows Store Apps in C#

How to Create a Custom TracDat Report With the Ad Hoc Reporting Tool

Microsoft Access 2010 Overview of Basics

Client Ordering and Report Retrieval Website

USER GUIDE Appointment Manager

Access Tutorial 3 Maintaining and Querying a Database. Microsoft Office 2013 Enhanced

Tutorial 3 Maintaining and Querying a Database

Data Tool Platform SQL Development Tools

CONTENTS MANUFACTURERS GUIDE FOR PUBLIC USERS

Abstract. For notes detailing the changes in each release, see the MySQL for Excel Release Notes. For legal information, see the Legal Notices.

5 Airport. Chapter 5: Airport 49. Right-click on Data Connections, then select Add Connection.

Understanding In and Out of XAML in WPF

Crystal Reports. For Visual Studio.NET. Designing and Viewing a Report in a Windows Application

ComponentOne. Windows for WPF

How To Integrate SAP Business Data Into SharePoint 2010 Using Business Connectivity Services And LINQ to SAP

BusinessObjects: General Report Writing for Version 5

SharePoint Integration Framework Developers Cookbook

Working with Data in ASP.NET 2.0 :: Paging and Sorting Report Data Introduction. Step 1: Adding the Paging and Sorting Tutorial Web Pages

Creating QBE Queries in Microsoft SQL Server

Lab 2: MS ACCESS Tables

AvePoint SearchAll for Microsoft Dynamics CRM

Microsoft Access 3: Understanding and Creating Queries

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

Visual C# 2012 Programming

Page Editor Recommended Practices for Developers

OCS Training Workshop LAB14. Setup

Access Tutorial 6: Form Fundamentals

Monitoring of Tritium release at PTC.

A SharePoint Developer Introduction. Hands-On Lab. Lab Manual HOL8 Using Silverlight with the Client Object Model C#

Microsoft SQL Server Staging

IBM Tivoli Software. Document Version 8. Maximo Asset Management Version 7.5 Releases. QBR (Ad Hoc) Reporting and Report Object Structures

Scheduling Software User s Guide

Parameter Fields and Prompts. chapter

2009 Braton Groupe sarl, All rights reserved.

HarePoint Workflow Scheduler Manual

OLAP Cube Manual deployment and Error resolution with limited licenses and Config keys

Building Database-Powered Mobile Applications

Developing Web Applications for Microsoft SQL Server Databases - What you need to know

Index. CloudBlockBlob class, 204 CreateDatabase() method, 217 Create, Read, Update, and Delete (CRUD) methods, 79 CSSCop, 17

Visual Basic. murach's TRAINING & REFERENCE

Developer s Guide. Tobii EyeX SDK for.net. October 27, 2014 Tobii Technology

SQL Server 2014 BI. Lab 04. Enhancing an E-Commerce Web Application with Analysis Services Data Mining in SQL Server Jump to the Lab Overview

Call Logging Quick Reference User Guide

This tutorial has been designed for all those readers who want to learn WPF and to apply it instantaneously in different type of applications.

Step One. Step Two. Step Three USING EXPORTED DATA IN MICROSOFT ACCESS (LAST REVISED: 12/10/2013)

M4 Systems. Batch & Document Management (BDM) Brochure

Introduction to Microsoft Access 2003

Hostname (DNS Resolvable) Network Objects

REP200 Using Query Manager to Create Ad Hoc Queries

This training module reviews the CRM home page called the Dashboard including: - Dashboard My Activities tab. - Dashboard Pipeline tab

Transcription:

آموزش DataGrid در WPF به همراه صفحه بندي و جستجوي انتخابی در پاپرو برنامه نویسی را شیرین یاد بگیرید کلیک کن www.papro-co.ir

WPF DataGrid Custom Paging and Sorting This article shows how to implement custom paging and sorting on a WPF DataGrid. Introduction WPF DataGrid has built-in functionality for sorting its items by clicking on a column header. However, it only works for the current items in the DataGrid. This becomes a problem when paging functionality is implemented. Paging is a must when items are so many that it should not be loaded into memory because it might affect performance. Application Let s create an application like the one below.

The window is made up of a data grid which shows a list of products and buttons for moving through the list. The data grid is a WPF DataGrid. It is not yet a released product but is downloadable from CodePlex under WPF Toolkit. Paging To implement paging, a method must be created that retrieves items from data storage where the calling method can specify the range of items that should be returned. The following code listing shows a static class that has the said method. /// Class that simulates a DataAccess module. public static class DataAccess /// A list of products. This should be replaced by a database. private static ObservableCollection<Product> products = new ObservableCollection<Product> new Product(1, "Book"), new Product(2, "Desktop Computer"), new Product(3, "Notebook"), new Product(4, "Netbook"), new Product(5, "Business Software"), new Product(6, "Antivirus Software"), new Product(7, "Game Console"), new Product(8, "Handheld Game Console"), new Product(9, "Mobile Phone"), new Product(10, "Multimedia Software"), new Product(11, "PC Game") ; /// Gets the products. /// <param name="start">zero-based index that determines the start of the products to be returned.</param> /// <param name="itemcount">number of products that is requested to be returned.</param>

/// <param name="sortcolumn">name of column or member that is the basis for sorting.</param> /// <param name="ascending">indicates the sort direction to be used.</param> /// <param name="totalitems">total number of products.</param> /// <returns>list of products.</returns> public static ObservableCollection<Product> GetProducts(int start, int itemcount, string sortcolumn, bool ascending, out int totalitems) totalitems = products.count; ObservableCollection<Product> sortedproducts = new ObservableCollection<Product>(); // Sort the products. In reality, the items should be stored in a database and // use SQL statements for sorting and querying items. switch (sortcolumn) case ("Id"): sortedproducts = new ObservableCollection<Product> ( from p in products orderby p.id select p ); break; case ("Name"): sortedproducts = new ObservableCollection<Product> ( from p in products orderby p.name select p ); break; sortedproducts = ascending? sortedproducts : new ObservableCollection<Product>(sortedProducts.Reverse()); ObservableCollection<Product> filteredproducts = new ObservableCollection<Product>(); for (int i = start; i < start + itemcount && i < totalitems; i++) filteredproducts.add(sortedproducts[i]); return filteredproducts; The GetProducts() determines the range of products to return by using the start and itemcount parameters. The sortcolumn and ascending parameters are used in sorting the items, which will be discussed later. The totalitems is an out parameter that is set by the method to the total

number of products. This can be more useful if there is a search function. The totalitems will be set to the number of products that matched the specified search criteria instead. Notice that the GetProducts() method only gets the products from a static member defined in the class. This is for demonstration purposes only. Accessing items from a database is more desirable. Now let s take a look at XAML definition of the window that was shown earlier and make a way to call the GetProducts() method. <Window x:class="wpfapp.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit" Width="350" Height="190" Title="WPF DataGrid Paging and Sorting"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <tk:datagrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="Binding Products"> <tk:datagrid.columns> <tk:datagridtextcolumn Header="PRODUCT ID" Binding="Binding Id" Width="*"/> <tk:datagridtextcolumn Header="PRODUCT NAME" Binding="Binding Name" Width="*"/> </tk:datagrid.columns> </tk:datagrid> <StackPanel Margin="4" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center"> <Button Margin="4,0" Content="<<" Command="Binding FirstCommand"/> <Button Margin="4,0" Content="<" Command="Binding PreviousCommand"/> <StackPanel VerticalAlignment="Center" Orientation="Horizontal"> <TextBlock

Text="Binding Start"/> <TextBlock Text=" to "/> <TextBlock Text="Binding End"/> <TextBlock Text=" of "/> <TextBlock Text="Binding TotalItems"/> </StackPanel> <Button Margin="4,0" Content=">" Command="Binding NextCommand"/> <Button Margin="4,0" Content=">>" Command="Binding LastCommand"/> </StackPanel> </Grid> </Window> The DataGrid s ItemsSource dependency property is bounded to the Products property in the window s ViewModel. The Products property is set to a new object every time a user clicks on a navigation button. Each button has its Command property bounded to a property in the ViewModel. If you are unfamiliar with Model-View-ViewModel design pattern, you may look at my previous article entitled WPF and the Model View View Model Pattern or you could search for other resources. Most of the logic is implemented in the window s ViewModel. The following code listing shows the ViewModel. /// ViewModel of the MainWindow. This is assigned to the MainWindow's DataContext /// property. Implements the INotifyPropertyChanged interface to notify the View /// of property changes. public class MainViewModel : INotifyPropertyChanged #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region Private Fields private ObservableCollection<Product> products; private int start = 0; private int itemcount = 5;

private string sortcolumn = "Id"; private bool ascending = true; private int totalitems = 0; private ICommand firstcommand; private ICommand previouscommand; private ICommand nextcommand; private ICommand lastcommand; #endregion /// Constructor. Initializes the list of products. public MainViewModel() RefreshProducts(); /// The list of products in the current page. public ObservableCollection<Product> Products get return products; private set if (object.referenceequals(products, value)!= true) products = value; NotifyPropertyChanged("Products");... /// Gets the index of the first item in the products list. public int Start get return start + 1; /// Gets the index of the last item in the products list. public int End get return start + itemcount < totalitems? start + itemcount : totalitems ;

/// The number of total items in the data store. public int TotalItems get return totalitems; /// Gets the command for moving to the first page of products. public ICommand FirstCommand get if (firstcommand == null) firstcommand = new RelayCommand ( start = 0; RefreshProducts();, return start - itemcount >= 0? true : false; ); return firstcommand; /// Gets the command for moving to the previous page of products. public ICommand PreviousCommand get if (previouscommand == null) previouscommand = new RelayCommand ( start -= itemcount; RefreshProducts();, return start - itemcount >= 0? true : false; ); return previouscommand;

/// Gets the command for moving to the next page of products. public ICommand NextCommand get if (nextcommand == null) nextcommand = new RelayCommand ( start += itemcount; RefreshProducts();, return start + itemcount < totalitems? true : false; ); return nextcommand; /// Gets the command for moving to the last page of products. public ICommand LastCommand get if (lastcommand == null) lastcommand = new RelayCommand ( start = (totalitems / itemcount - 1) * itemcount; start += totalitems % itemcount == 0? 0 : itemcount; RefreshProducts();, return start + itemcount < totalitems? true : false; ); return lastcommand;

/// Refreshes the list of products. Called by navigation commands. private void RefreshProducts() Products = DataAccess.GetProducts(start, itemcount, sortcolumn, ascending, out totalitems); NotifyPropertyChanged("Start"); NotifyPropertyChanged("End"); NotifyPropertyChanged("TotalItems"); /// Notifies subscribers of changed properties. /// <param name="propertyname">name of the changed property.</param> private void NotifyPropertyChanged(string propertyname) if (PropertyChanged!= null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); The ViewModel contains the commands for navigating through the list of products. Basically, these commands just set the start variable then call the RefreshProducts() method. For example, the FirstCommand just sets the start variable to the value 0. Afterwards, it calls the RefreshProducts() method which in turn calls the DataAccess.GetProducts() method which uses the updated start variable. The itemcount value is not changed anywhere in the application. It is useful when a user wants to select the number of items that can be displayed. This is a common functionality in most applications that implement paging. This is not implemented in the example. Sorting Now that paging has been implemented, the only thing left is custom sorting. The following screenshot shows a sorted list of products if the data grid s built-in sorting is used.

In the example, the product name is sorted. Notice that only the items that were sorted are the current items in the data grid. The items stored in our data store are not included in the sort. The following screenshot shows the sorted list of products where custom sorting was used. To implement custom sorting, some code changes need to be done. The following code listing shows the updated data grid definition in the XAML file. <tk:datagrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="Binding Products, NotifyOnTargetUpdated=True" Sorting="ProductsDataGrid_Sorting" TargetUpdated="ProductsDataGrid_TargetUpdated" Loaded="ProductsDataGrid_Loaded"> <tk:datagrid.columns> <tk:datagridtextcolumn Header="PRODUCT ID" Binding="Binding Id" Width="*" SortDirection="Ascending"/> <tk:datagridtextcolumn Header="PRODUCT NAME" Binding="Binding Name" Width="*"/> </tk:datagrid.columns> </tk:datagrid>

Notice that the following event handlers are added: ProductsDataGrid_Sorting, ProductsDataGrid_TargetUpdated and ProductsDataGrid_Loaded. Also, the NotifyOnTargetUpdated property of the ItemsSource s binding is set to true. The following code listing shows the code-behind file of the window. This shows the definition for the event handlers previously mentioned. /// Interaction logic for MainWindow.xaml public partial class MainWindow : Window private DataGridColumn currentsortcolumn; private ListSortDirection currentsortdirection; public MainWindow() InitializeComponent(); DataContext = new MainViewModel(); /// Initializes the current sort column and direction. /// <param name="sender">the products data grid.</param> /// <param name="e">ignored.</param> private void ProductsDataGrid_Loaded(object sender, RoutedEventArgs e) DataGrid datagrid = (DataGrid)sender; // The current sorted column must be specified in XAML. currentsortcolumn = datagrid.columns.where(c => c.sortdirection.hasvalue).single(); currentsortdirection = currentsortcolumn.sortdirection.value; /// Sets the sort direction for the current sorted column since the sort direction /// is lost when the DataGrid's ItemsSource property is updated. /// <param name="sender">the parts data grid.</param> /// <param name="e">ignored.</param> private void ProductsDataGrid_TargetUpdated(object sender, DataTransferEventArgs e) if (currentsortcolumn!= null) currentsortcolumn.sortdirection = currentsortdirection; /// Custom sort the datagrid since the actual records are stored in the

/// server, not in the items collection of the datagrid. /// <param name="sender">the parts data grid.</param> /// <param name="e">contains the column to be sorted.</param> private void ProductsDataGrid_Sorting(object sender, DataGridSortingEventArgs e) e.handled = true; MainViewModel mainviewmodel = (MainViewModel)DataContext; string sortfield = String.Empty; // Use a switch statement to check the SortMemberPath // and set the sort column to the actual column name. In this case, // the SortMemberPath and column names match. switch (e.column.sortmemberpath) case ("Id"): sortfield = "Id"; break; case ("Name") : sortfield = "Name"; break; ListSortDirection direction = (e.column.sortdirection!= ListSortDirection.Ascending)? ListSortDirection.Ascending : ListSortDirection.Descending; bool sortascending = direction == ListSortDirection.Ascending; mainviewmodel.sort(sortfield, sortascending); currentsortcolumn.sortdirection = null; e.column.sortdirection = direction; currentsortcolumn = e.column; currentsortdirection = direction; First, the current data grid column and sort direction are stored in member variables because the current sort information is lost when the DataGrid s ItemsSource property is set to another instance, which will be done every time the user sorts the list or navigates to other pages. These variables are initialized in the Loaded event handler of the window. Note that there must be one column that has its SortDirection property initialized by specifying it either in code or XAML. To set the sort direction again when a user sorts the list or moves to another page, the current column s SortDirection property should be set in the TargetUpdated event handler. The event is triggered when the DataGrid s ItemsSource property is updated. The NotifyOnTargetUpdated property in the binding expression should be set to true. Take note that setting the sort direction does not sort the data grid. It just specifies how the sort arrow of the column should be displayed.

The Sorting event handler overrides the default sorting mechanism of the data grid. The Handled property of the DataGridSortingEventArgs parameter must be set to true so that the default sorting is not executed. This method calls the newly added Sort() method of the MainViewModel. It requires two parameters, the sort column and the sort direction. The application should know beforehand the possible values for the sort column. The possible values may be defined as an enumeration type in the DataAccess module. I just used a string for simplicity. The direction variable is a local variable that stores the next sort direction. Basically, it toggles the sort direction for the column that is to be sorted. Meanwhile, the sort direction for the current column that is sorted is set to null. Finally, the currentsortcolumn and currentsortdirection are set to their new values. The Visual Studio 2008 example can be downloaded here.