-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Implements Carousel control and sample carousel page #712
Conversation
Hi @Mimetis, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution! TTYL, DNFBOT; |
@Mimetis, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages | ||
{ | ||
/// <summary> | ||
/// A page that shows how to use the DropShadowPanel control. |
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 shouldn't be DropShadowPanel control :)
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.
ah ah correct :) Copy / Paste "is not" a friend !!
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" | ||
xmlns:local="using:Microsoft.Toolkit.Uwp.SampleApp.SamplePages" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
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.
you need to use XamlStyler in Xaml pages
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.
TransitionDuration="{Binding TransitionDuration.Value, Mode=OneWay}" | ||
Depth="{Binding Depth.Value, Mode=OneWay}" | ||
MaxVisibleItems="{Binding MaxVisibleItems.Value, Mode=OneWay}" | ||
x:Name="carouselControl" |
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.
The name Should start with Capital letter CarouselControl
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 .
Why I can't move using keyboard ? I guess it will be helpful as it was the first thing I do when I browse images on any slider is to move using keyboard arrows. |
When I change the selected item using touch or mouse, the SelectedIndex slider in the properties Window became useless as when manipulating it nothing happens |
mc:Ignorable="d"> | ||
|
||
|
||
|
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 all this spaces ?
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.
Thx, I have made the corrections
using Microsoft.Toolkit.Uwp.SampleApp.Models; | ||
using System; | ||
using System.Collections.ObjectModel; | ||
using System.Linq; |
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.
The using statements need to be rearranged and the non used need to be removed.
datas.Add(new CarouselData { BitmapImage = new BitmapImage(new Uri("ms-appx:///Assets/Photos/NovemberHikeWaterfall.png", UriKind.Absolute)), Title = "14" }); | ||
datas.Add(new CarouselData { BitmapImage = new BitmapImage(new Uri("ms-appx:///Assets/Photos/Owl.png", UriKind.Absolute)), Title = "15" }); | ||
|
||
this.Datas = datas; |
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.
Please remove this keyword as it is useless.
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.
Well, to be honest, using this or not is a "coding style" and I use "this" every time I can, to make my code the most readable as possible.
I know we can have a long long debate about this.
But anyway, is adding "this" or not, Something so important in this case ? :)
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 important as it is part of our guideline :) we need to keep the same coding style for the entire project
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.
Ok, I will delete all the "this" keywords if they're not necessary :)
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Collections.Specialized; | ||
using System.Linq; |
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.
Please remove the unused namespaces
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.
{ | ||
public class Carousel : Canvas | ||
{ | ||
private double initialOffset; |
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 is not using the Standard library rules for documentations and naming conventions
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.
The last version has changed, can you take a look on it ?
@Mimetis up ? |
|
||
if (this.SelectedIndex == index) | ||
{ | ||
this.SelectedIndex = this.SelectedIndex == 0 ? 0 : this.SelectedIndex - 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.
If the last item is removed, SelectedIndex should become -1. Here it would end up with 0.
…control, new Orientation Property, Performance increase.
Hey @Mimetis,do you think you can implement the requested changes? Thank you :) |
|
||
<Border Margin="0"> | ||
|
||
<controls:Carousel ItemsSource="{Binding Datas}" Background="{StaticResource Brush-Grey-05}" |
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.
Make sure xaml in the bind file matches the xaml in the actual page
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
<controls:Carousel.ItemTemplate> | ||
<DataTemplate> | ||
<Grid > | ||
<Grid.RowDefinitions> |
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.
No need for the Rows or even the Grid itself. Template can just be the Image
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.
Right, corrected
@@ -0,0 +1,52 @@ | |||
<Page x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.Carousel" |
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.
Class name should have the 'Page' suffix
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.
Right, corrected
<RowDefinition Height="Auto" /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
<Image Width="200" |
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.
Make sure all xaml has gone through the xaml styler: https://github.com/Microsoft/UWPCommunityToolkit/blob/master/contributing.md#quality-insurance-for-pull-requests-for-xaml-controls
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.
Right, corrected
DataContext = propertyDesc.Expando; | ||
} | ||
|
||
var datas = new ObservableCollection<CarouselData>(); |
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.
Images can be obtained from the PhotosDataSource
class.
carouselControl.ItemsSource = await new Data.PhotosDataSource().GetItemsAsync()
All of the images were actually changed from pngs to jpgs recently
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.
Thx for the tips, I changed the way sample work :)
this.ManipulationMode = ManipulationModes.All; | ||
this.IsHitTestVisible = true; | ||
|
||
this.SubscribePropertyChanged("ItemsSource", OnCarouselPropertyChanged); |
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.
Use RegisterPropertyChangedCallback method to handle the ItemsSource changing, or listen to the Items.VectorChanged event to know when items have been added/removed/changed
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.
Right, corrected
{ | ||
base.PrepareContainerForItemOverride(element, item); | ||
|
||
if (this.ItemTemplate == 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.
Why not create a new CarouselItem to handle displaying the content and handle the transform? Then each CarouselItem could have the dependency properties required for render transform
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 don't want to create a specialized item (CarouselItem) for each 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.
Any reason why? I think it could simplify some things
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.
Easier for the developer to submit an ItemTemplate based on a ContentControl than a CarouselItem, in my opinion :)
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.
How so? The fact that a ListView uses a ListViewItem does not change how a user defines an ItemTemplate
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.
Oh Yes, my bad you're right on this point.
Anyway, adding a CarouselItem implies adding a new control class and a new style.
I want to have something the most simpliest.
Adding a CarouselItem is, in my point of view, a good thing if we need events and so on on each 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.
If the transform/animation stuff was to really be improved (in a future version), it should be changed to use Composition. As far as I understand, Composition does not work well with normal DPs, so introducing CarouselItems now and controlling them through DPs might go into the wrong direction. Just my 2 cents...
|
||
namespace Microsoft.Toolkit.Uwp.UI.Controls | ||
{ | ||
public class CarouselPanel : Panel |
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.
Any reason the functionality of this class is not in the Carousel control itself?
What happens if I use a CarouselPanel directly in my xaml? What happens if I use it as the panel for a ListView?
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 won't work.
This CarouselPanel is needed because you want an ItemsControl.
That's why, when you create an object inheriting from ItemsControl, if you follow the guidelines and how it's implemented in object like ListView, you should create an ItemsPanel.
For Carousel , the problem is that the only ItemsTemplate that works is the CarouselPanel.
And in the other side, the only ItemsControl that could work with a CarouselPanel is the Carousel control.
Maybe in a next release, we could try to resolved this design problem :)
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 my understanding as well. On top of this, if you want to layout items, Panel is the way to go. However, Panel can't be focused and can't get keyboard/controller events, so you need a Control (such as the ItemsControl). I ran into the same "issue" in my implementation, and I believe this is by design
continue; | ||
} | ||
|
||
this.Carousel.SelectedIndex = i; |
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.
No guarantee that the panel will be placed within a Carousel
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 Change the Carousel getter to raise an error if we use this panel in other ItemsControl
{ | ||
var position = e.GetPosition(this); | ||
|
||
for (int i = 0; i < this.Children.Count; i++) |
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.
If there was a CarouselItem, it could listen to tap events and set itself as the selected item. The Carousel could listen to the CarouselItem changing this and set it's own property.
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.
Don't remember exactly why I made it like this, but in my opinion:
- I don't want CarouselItem, to let more flexibility to developers
- I think I made it like that because of Virtualization (less events to subscribe)
Started a review, but after reviewing the CarouselPanel I stopped to think, "Can this be a ListViewBase?" Is there any reason not to make this a ListViewBase control? It's possible that the manipulation code can be replaced by using a ScrollViewer and setting the Vertical and HorizontalSnapPointsType. Thoughts? |
I think ListViewBase raise too many events and set to many properties in my opinion. |
@nmetulev @IbraheemOsama Do you mind guys updating your reviews based on latest commits? |
@@ -68,11 +68,17 @@ | |||
<WebView Name="webView" | |||
Grid.Row="0" | |||
Visibility="Collapsed" /> | |||
<Button x:Name="PrintButton" |
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.
woot?
@nmetulev your last commit is suspicious :) |
Should be good now @deltakosh @Mimetis, I updated the focus to work for Xbox better and added the automation property. However, working on the automation property I realized that we should change how focus works on the control so it focuses on each item instead of the control itself. Could you take a look at it and see what it would take to do that? For me, that and the sudden jump to an item on inertial scrolling are the last two things that should be fixed. |
Ping @Mimetis |
I'm currently working on the "sudden jump" behavior. But it's ... complicated :) |
Do you think you can make it before 3/21? |
I really dont know. And for the tab control, I have to make some implementations, to see if the behavior is correct. So, for now, if those requests are mandatory, the response is No :) For instance the control is actually working pretty well, maybe we could schedule these improvements for a next version ? |
Just added code to change the tabstop to be on the items and use arrow focus. I'll take a look at the inertia if I have time tomorrow; otherwise I'll let you know. |
Thx @nmetulev I just tried your solution about tabstop and it's working pretty well. Nice job ! |
We will check for the sudden jump. can you create the documentation? |
I spent a bit of time investigating the sudden jump, and tried to resolve it by canceling the inertia when detected and running the animation to the closes item where the inertia would have ended (by calculating the speed and deceleration of the inertia). It seems to be promising, but it still has some issues which I don't think I can resolve this week. My proposal is to merge the PR as soon as the docs are added, and we open a bug for this issue? I pushed my work so far here. @Mimetis , could you take a look and see if this make sense? You know the code much better, and I'm hoping my experimentation might give you an idea :) |
perfectly fine with that. I'll merge as soon as we have a doc |
Thx @nmetulev for your awesome work ! It's an interesting work, and I think we should work on it more if we want to release something based on the inertia interruption. I will work right now on the documentation, since this problem won't affect the documentation, but we have to decide what kind of manipulation behavior we want |
That's what I call a doc:) |
I'm merging now. If someone found something wrong please open an issue |
Congrats @Mimetis ! |
Implementing a first version of the Carousel control.