New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] AdvancedCollectionViewSource #349
[WIP] AdvancedCollectionViewSource #349
Conversation
Hi @tomzorz, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! TTYL, MSBOT; |
@tomzorz, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
This is REALLY cool. It is a big amount of work though. To all: Do not hesitate to use this issue (#248) to discuss about architecture or whatever else you may need. |
Edited the original comment, I added the done section. |
using Windows.Foundation.Collections; | ||
using Windows.UI.Xaml.Data; | ||
|
||
namespace Microsoft.Toolkit.Uwp.UI.Controls.AdvancedCollectionViewSource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should not be in its own namespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
....nor in a UI.Controls
namespace since it's neither
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. The built-in one is in .Xaml.Data - https://msdn.microsoft.com/library/windows/apps/br209833?f=255&MSPPError=-2147217396 - I'd move it to the .UI project under the Data namespace based on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.UI should be enough (no need for .Data)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved it.
HandleSourceChanged(); | ||
} | ||
|
||
public IEnumerator<object> GetEnumerator() => _view.GetEnumerator(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties order is not aligned to Stylecop checks here (You must have warnings for that when compiling)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a quick little initial review
using Windows.Foundation.Collections; | ||
using Windows.UI.Xaml.Data; | ||
|
||
namespace Microsoft.Toolkit.Uwp.UI.Controls.AdvancedCollectionViewSource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
....nor in a UI.Controls
namespace since it's neither
return; | ||
} | ||
|
||
CurrentChanging?.Invoke(this, e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this event needed? Wouldn't it be better to have oldValue
and newValue
in the event arguments of the CurrentChanged
event?
Also why virtual? If the intent is to subclass and ovewrite this event to handle when the item is changing, generally this should be an empty method to override, so the content of this code still executes if the subclass doesn't call base.OnCurrentChanging
(same for OnCurrentChanged
and OnVectorChanged
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this event needed? Wouldn't it be better to have oldValue and newValue in the event arguments of the CurrentChanged event?
The implementations are this way because of ICollectionView's requirements. (They are only used for the defer notifications part.)
Also why virtual?
True. Removed virtual, and made it private.
_sourceNcc = _source as INotifyCollectionChanged; | ||
if (_sourceNcc != null) | ||
{ | ||
_sourceNcc.CollectionChanged += _sourceNcc_CollectionChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a weak listener
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is now.
MoveCurrentTo(currentItem); | ||
} | ||
|
||
private void _sourceNcc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the naming of this method creating a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also fixed.
switch (e.Action) | ||
{ | ||
case NotifyCollectionChangedAction.Add: | ||
if (e.NewItems.Count == 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NewItems could be null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
/// </summary> | ||
/// <param name="item">item</param> | ||
/// <returns>success of operation</returns> | ||
public bool MoveCurrentTo(object item) => item == CurrentItem || MoveCurrentToIndex(IndexOf(item)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have this when you already have the CurrentItem property that is get and set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ICollectionView implementation.
/// <exception cref="NotImplementedException">Not implemented yet...</exception> | ||
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) | ||
{ | ||
throw new NotImplementedException("todo..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to be completed. I assume it's just a matter of checking if the source implements ISupportIncrementalLoading and call LoadMoreItemsAsync on that ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/// <summary> | ||
/// Gets a value indicating whether the source has more items | ||
/// </summary> | ||
public bool HasMoreItems => false; // todo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just:
public bool HasMoreItems => (_source as ISupportIncrementalLoading)?.HasMoreItems ?? false;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it is - added.
/// <summary> | ||
/// Occurs when the vector changes. | ||
/// </summary> | ||
public event VectorChangedEventHandler<object> VectorChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not INotifyCollectionChanged instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required IObservableVector implementation.
/// <summary> | ||
/// Vector changed EventArgs | ||
/// </summary> | ||
public class VectorChangedEventArgs : IVectorChangedEventArgs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this class can be kept internal. It's enough to have IVectorChangedEventArgs public which is already part of WinRT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Thanks for the reviews - I'll try to work on the issues this weekend. |
Pull from main MS repo
…ixes and other misc. changes.
Aaand, third time's the charm :) I left some questions above before proceeding with certain fixes. |
This is really good work! It 's gonna be a truly awesome addition to the toolkit |
Hey! How things are going here? |
@deltakosh got an exam tomorrow - I'm planning on finishing the remaining issues later this week :) |
Ouch!! good luck :) |
Getting new changes
Getting new changes
Ok keep me posted. There is no problem to flag it for 1.3 |
@deltakosh Let's flag it for 1.3 - I want to do this right, but I don't have time for right until 1.2 :D (maybe I'll have some down time during the summit) |
Completely aligned! |
I haven't forgot about the PR - definitely planning on to finish it before 1.3 :) |
OK thanks:) |
/// <summary> | ||
/// Extended ICollectionView with filtering and sorting | ||
/// </summary> | ||
public interface ICollectionViewEx : ICollectionView |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not call it "IAdvancedCollectionView" to match the class name.
Or "ICollectionViewSource" if the class name is named "CollectionViewSource"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I'll do that.
/// <summary> | ||
/// Gets or sets the predicate used to filter the visisble items | ||
/// </summary> | ||
public Predicate<object> Filter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have to create a delegate type rather than use Predicate.
If we want to add new behavior on the filtering it will be easy without make breaking changes.
In the Silverlight implementation of CollectionViewSource they create a delegate called FilterEventHandler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd personally go with the functional-ish/linq-ish style of the predicate, rather than have events instead. Also we can always ease-in breaking changes by marking things obsolete first. But I guess this is open for discussion.
Very good work. I cant wait to have it in the toolkit. :) |
bool CanFilter { get; } | ||
|
||
/// <summary> | ||
/// Gets or sets the predicate used to filter the visisble items |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the summary block => "visisble" must be "visible"
Up? :) and Happy new year 💃 |
@deltakosh Yes! Sorry, planning on wrapping it up this weekend. |
You rock! |
Merge from MS
# Conflicts: # UnitTests/UnitTests.csproj
So theoretically this is it, pinging @deltakosh for a final re-check. |
/// <summary> | ||
/// Sort description | ||
/// </summary> | ||
public class SortDescription |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have you named it SortDescription ? shouldn't it be SortDirection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just a direction - it describes a sorting step: a property to sort on plus the direction. So you can have more of these, and for example it'll sort by prop A asc, then by prob B desc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whilst its specifying a sort, calling it a SortDescription is misleading. I think you should call it SortDirection, SortEntry or something else. yes I get that you can add more than one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe SortLevel, to match the phrasing that Excel uses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm for SortDescription actually. It makes sense to me
@@ -0,0 +1,2 @@ | |||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should not be in the repo
@@ -273,7 +273,7 @@ | |||
<CodeAnalysisRuleSet>microsoft.toolkit.uwp.ui.controls.ruleset</CodeAnalysisRuleSet> | |||
</PropertyGroup> | |||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" /> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessary update ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah, apparently VS was automatically removing that space from the end of the line any time I saved... had to edit it back in VSCode :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small changes only..Really good job
@deltakosh done :) Thanks! |
@dotMorten @hermitdave Fancy doing a second check? Thanks! |
@deltakosh I already went through the code.. I don't see any significant changes since then.. maybe @dotMorten can take a look.. good from my side |
Do you mind flagging it as approved? |
This is a work in progress for issue #248
Right now I only did the suggested formattings to the original code.
Skipped for now:
Done:
Edited: 2016.10.09., 2016.10.22., 2017.01.07.