WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.7' for table 'wp_options']INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1715718949.9638020992279052734375', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)
<\/a>For each item list used in a WPF application, a collection view is in fact created and used by the controls. This view enables navigation, filtering, grouping and sorting from the XAML or the code. It is a very powerful feature that is offered to the developers since a long time in WPF.<\/p>\n In WPF 4.5 as in WPF 4.0 the grouping, sorting and filtering operations are done when the item is added to the collection or when the Refresh method is called. The drawback is that if an item property value involved in one of these operations is updated, then the sorting\/grouping\/filtering will not be done again.<\/p>\n WPF 4.5 introduce a feature called live shaping which shapes the collection view in live. Let’s dig a little more this feature.<\/strong><\/p>\n This post is the tenth part of a serie on the WPF 4.5 new features<\/a>.<\/p>\n <\/p>\n When you use a collection in WPF, it’s in fact its default view which is used by the controls. You should read Bea Stollnitz’s post on this feature<\/a> if you want more information.<\/p>\n You can retrieve the default view on the collection by using the CollectionViewSource <\/em>static method named GetDefaultView<\/em>: The ICollectionView interface exposes methods which enable grouping and sorting<\/strong> described via the GroupDescriptions and SortDescriptions collection respectively. The grouping can then be used in ItemsControl by setting the GroupStyle property. In the snippet below, the persons are sorted and grouped by age: \/\/sort by age Also, a predicate can be defined to tells if an item is exposed or not by the view on the collection.<\/strong> In this example we do not expose children(under 18): \/\/Children are not accepted The items are filtered, sorted and grouped on two occasions:<\/p>\n This is fine but it does not cover every possible scenario. For example, if an item update the value of the property on which one of this operation is done, no refreshing is done. <\/strong><\/p>\n To illustrate this, I created a little demo which groups and sort a collection of persons by age and removes the one under 18. It can be found on my Dropbox folder after registration<\/a>. A button, changes randomly the age of the persons. An another adds one year to each of the persons of the collection. After several click on those buttons, it ends up with a list displaying strange things: the groups are no more representative and the persons are no more sorted. More over, there is children(under 18) who are displayed and some who are not : This can be a wanted feature as you may want the collection display to be updated in live. If so, the live shaping is here for you in WPF 4.5 !<\/p>\n This new feature is an opt-in one. You can activate live sorting, live grouping and live filtering separately and by default each is disabled.<\/strong><\/p>\n The ICollectionView<\/em> interface is still the same and nothing more is exposed. However you have to use a new interface named ICollectionViewLiveShaping<\/em><\/strong>. <\/p>\n There is three properties relative to each operation (grouping, sorting, filtering):<\/strong><\/p>\n The most important one is maybe the last. When you define a sorting, a grouping or a filter, some property of the contained items are involved. By adding a property name in the LiveXXXProperties collection The process to activate one operation is this one:<\/p>\n <\/strong><\/p>\n I created some helpers for the above demo application which activate each of them.<\/p>\n [csharp] private void ActiveLiveSorting(ICollectionView collectionView, [\/csharp]<\/p>\n [csharp] private void ActiveLiveGrouping(ICollectionView collectionView, [\/csharp]<\/p>\n [csharp] private void ActiveLiveFiltering(ICollectionView collectionView, [\/csharp]<\/p>\nBasic behavior<\/h3>\n
\n[csharp] var collectionView
\n = CollectionViewSource.GetDefaultView(Persons) as ICollectionView;[\/csharp]<\/p>\n
\n[csharp]\/\/Group by age
\ncollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Age"));<\/p>\n
\ncollectionView.SortDescriptions.Add(new SortDescription("Age",
\n ListSortDirection.Ascending));
\n[\/csharp]<\/p>\n
\n[csharp]
\nprivate void ApplyFilter(ICollectionView collectionView)
\n{
\n \/\/Apply the filter
\n collectionView.Filter = IsPersonAccepted;
\n}<\/p>\n
\npublic bool IsPersonAccepted(object item)
\n{
\n Person p = item as Person;
\n return (p != null) && p.Age > 18;
\n}
\n[\/csharp]<\/p>\n\n
\n<\/a><\/p>\nLive shaping<\/h3>\n
\n
\n you tell the framework: on each change of the property with this name, you have to refresh the operation XXX<\/strong>. As you can have guessed, it works using the INotifyPropertyChanged interface. The collection view register to each of the item added to the collection and listen for changes at the aimed properties. Simple as that !<\/p>\n\n
Live sorting<\/h3>\n
\n \/\/In a method before
\n ActiveLiveSorting(collectionView, new List<string>("Age");
\n \/\/ …<\/p>\n
\n IList<string> involvedProperties)
\n{
\n var collectionViewLiveShaping = collectionView as ICollectionViewLiveShaping;
\n if (collectionViewLiveShaping == null) return;
\n if (collectionViewLiveShaping.CanChangeLiveSorting)
\n {
\n\t foreach(string propName in involvedProperties)
\n collectionViewLiveShaping.LiveSortingProperties.Add(propName);
\n collectionViewLiveShaping.IsLiveSorting = true;
\n }
\n}<\/p>\nLive grouping<\/h3>\n
\n \/\/In a method before
\n ActiveLiveGrouping(collectionView, new List<string>("Age");
\n \/\/ …<\/p>\n
\n IList<string> involvedProperties)
\n{
\n var collectionViewLiveShaping = collectionView as ICollectionViewLiveShaping;
\n if (collectionViewLiveShaping == null) return;
\n if (collectionViewLiveShaping.CanChangeLiveGrouping)
\n {
\n\t\tforeach(string propName in involvedProperties)
\n collectionViewLiveShaping.LiveGroupingProperties.Add(propName);
\n collectionViewLiveShaping.IsLiveGrouping = true;
\n }
\n}<\/p>\nLive filtering<\/h3>\n
\n \/\/In a method before
\n ActiveLiveFiltering(collectionView, new List<string>("Age");
\n \/\/ …<\/p>\n
\n IList<string> involvedProperties)
\n{
\n var collectionViewLiveShaping = collectionView as ICollectionViewLiveShaping;
\n if (collectionViewLiveShaping == null) return;
\n if (collectionViewLiveShaping.CanChangeLiveFiltering)
\n {
\n\t\tforeach(string propName in involvedProperties)
\n collectionViewLiveShaping.LiveFilteringProperties.Add(propName);
\n collectionViewLiveShaping.IsLiveFiltering = true;
\n }
\n}<\/p>\n