xamarin 4.2 CarouselView automatic slider - c#

Is there a way to make automatic these changes of image on a carouselView in xamarin 4.2? I named the xamarin forms version because in this version there is a CarouselView, so I am not able to use the old nuget.org/packages/Xamarin.Forms.CarouselView/2.3.0-pre1
In that old version there was a Position property which cold be set to any item in this new version included on xamarinForms 4.2, that property is missing
What I want to create is something to show a different image every 4 seconds, do you have any suggestion?

i have create automatic slider using the following code in constructor.
Device.StartTimer(TimeSpan.FromSeconds(5), () =>
{
if (listOfSpotlight.Count == 0 || listOfSpotlight == null)
{
return true;
}
slidePosition++;
if (slidePosition == listOfSpotlight.Count) slidePosition = 0;
caroselView.Position = slidePosition;
return true;
});

The Xamarin.Forms.CarouselView has been having a bunch of issues lately and I am not sure how exactly all of a sudden Xamarin decided to add it to the 4.2 release. Also it seems as if there are no properties in it which is weird. Anyway, I was facing weird issues with Xamarin's Carousel so I started using the CarouselView.FormsPlugin and it works amazingly in all situations.
Nuget: https://www.nuget.org/packages/CarouselView.FormsPlugin/
Github: https://github.com/alexrainman/CarouselView
FYI it has all the properties that XF carousel does and more:
Add the following namespace:
xmlns:controls="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"
And then use it something like this:
<controls:CarouselViewControl Orientation="Horizontal" InterPageSpacing="10" Position="{Binding myPosition}" ItemsSource="{Binding myItemsSource}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<controls:CarouselViewControl.ItemTemplate>
<DataTemplate>
<local:MyView /> <!-- where MyView is a ContentView -->
</DataTemplate>
</controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl>
For finding additional properties look for Bindable Properties section of the homepage at Git.

You can try Chetan Rawat's answer or
Device.StartTimer(TimeSpan.FromSeconds(4), (Func<bool>)(() =>
{
cView.Position = (cView.Position + 1) % imagesList.Count;
return true;
}));
*here cView is my carousel view and imageList is my list that contains the images that have to be slided in carousel view .
Happy Coding :)

Related

Xamarin forms Carousel view does not allow skipping position

So i am trying to implement a wizard using carousel view that has next and previous buttons. For some reason the carousel view does not allow me to navigate multiple positions. For example if the view is currently at position 0 and i want to jump to position 2 it will go to position 1.
So view in xaml:
<CarouselView CurrentItemChanged="CurrentCarouselItemChanged" x:Name="EventWizardCarouselView" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Grid.Row="0">
<CarouselView.ItemsSource>
<x:Array Type="{x:Type ContentView}">
<views:EventBasicInfoView x:Name="eventWizardViewEventBasicInfo"/>
<views:EventRulesView x:Name="eventWizardViewEventRules"/>
<views:EventLocationsView x:Name="eventWizardViewEventLocations"/>
</x:Array>
</CarouselView.ItemsSource>
<CarouselView.ItemTemplate>
<DataTemplate>
<ContentView Content="{Binding .}"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
private void OnNextClicked(object sender, EventArgs e) {
EventWizardCarouselView.Position = 2;
OnPropertyChanged("Position");
}
Moral of the story here is that when in position 0 and i programatically set it to position 2 it will display position 1? However from position 1 it will go to position 2 just fine?
I was able to solve this on UWP by turning off animation. This is more of a band-aid than a fix but works for now. For those that run into this note that animation is set to true by default and i had to use ScrollTo(index, groupindex, type, false).
On Android, set the CurrentItem property of the carouselview. On iOS, set the Position property. Something like this code:
if (Device.RuntimePlatform == Device.Android) {
var selected = YourViewModelCollection[2];
EventWizardCarouselView.CurrentItem = selected;
} else if (Device.RuntimePlatform == Device.iOS) {
EventWizardCarouselView.Position = 2;
}
There are two kinds of way to change position of CarouselView , however the effects of animation all will show the middle position when skipping position.
One is using CurrentItem or Position , they all can used in Android /iOS even in UWP (if no problem when running UWP).
CurrentItem, of type object, the current item being displayed. This property has a default binding mode of TwoWay, and has a null value when there isn't any data to display.
eg : carouselView.CurrentItem = viewmodel;
Position, of type int, the index of the current item in the underlying collection. This property has a default binding mode of TwoWay, and has a 0 value when there isn't any data to display.
eg :carouselView.Position= position;
Another is using Scrolling .
carouselView.ScrollTo(position);
or
carouselView.ScrollTo(ViewModel);
Note :
Not too much focus on UWP , because CarouselView is available on iOS and Android, but some functionality may only be partially available on the Universal Windows Platform.
And CarouselView is a preview Control which statrs available in Xamarin.Forms 4.3.
I have not found the "real" solution for this problem, but I developed a quick workaround that looks nice enough.
In my app I got 3 tabs. Moving by 1 tab works fine so I just check if I want to got from the first to the last or the other way round and then just make it two movements:
if (Device.RuntimePlatform == Device.iOS
&& Math.Abs(oldIndex - newIndex) > 1) // Tab index is changed by 2?
{
_carouselView.ScrollTo(1);
// Second move after delay
Task.Delay(500).ContinueWith((_) => Device.BeginInvokeOnMainThread(() =>
_carouselView.ScrollTo(newIndex)),
TaskScheduler.FromCurrentSynchronizationContext()
);
}
else
{
_carouselView.ScrollTo(newIndex);
}
No customer complained so far :-)

Timer not working for an automatic CarouselView

I'm making an automatic CarouselView (slider) to slide between images every x seconds. I know there are plenty of examples but none of them helped me to make mine work. So here is the deal:
This is my xaml page:
<CarouselView x:Name="carou_slideshow" Grid.Row="1" IsVisible="False">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Whenever the user clicks on the button to start the slideshow, it shows my carousel with its images without any issue but it doesn't change the current image after x seconds. Here's how I've done it :
private void btn_slideShow_Clicked(object sender, EventArgs e)
{
stk_header.IsVisible = false;
stk_options.IsVisible = false;
grid_images.IsVisible = false;
carou_slideshow.IsVisible = true;
carou_slideshow.ItemsSource = sources;
Device.StartTimer(TimeSpan.FromSeconds(5), (Func<bool>)(() =>
{
carou_slideshow.Position = (carou_slideshow.Position + 1) % sources.Count;
return true;
})
);
}
Any idea why ?
EDIT : I realized that in my project I already had a timer in the same class. After removing it and keeping the one in the button method, my application crashes without any error.
EDIT2 : Someone gave me a solution on this post and deleted it after. I tried it and it doesn't work for me.. As I was sure it would, I tried to increment something else and the timer works perfectly fine, but the image doesn't swipe. Also, it can randomly close the application as well as not having any issue.

CarouselView xamarin forms conflicting Xamarin forms error

I have been working with CarouselView while using the Nuget Package Xamarin.Forms.CarouselView. I have tried to display the images as auto sliding.
XAML
<StackLayout Grid.Row="0" Grid.ColumnSpan="4">
<cv:CarouselView x:Name="MainCarouselView" Position="{Binding PositionIndex, Mode=TwoWay}">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding .}"></Image>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView >
</StackLayout>
C#
var image = new ObservableCollection<ImageSource>
{
ImageSource.FromFile("Image1.jpg"),
ImageSource.FromFile("Image2.jpg"),
ImageSource.FromFile("Image3.jpg")
};
MainCarouselView.ItemsSource = image;
Device.StartTimer(TimeSpan.FromSeconds(2), (Func<bool>) (() =>
{
MainCarouselView.Position = (MainCarouselView.Position + 1) % image.Count;
return true;
}));
After running the app on the device or emulator I get this error:
Severity Code Description Project File Line Suppression State Error CS0433 The type 'CarouselView' exists in both
'Xamarin.Forms.CarouselView, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' and 'Xamarin.Forms.Core, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=null'
I have tried to delete the Nuget Package and tried then the CarouselView remains empty and it also does not contain the property of Position. Any help will be appreciated.
EDIT: I have solved using CarouselView.FormsPlugin
Xaml:
<controls:CarouselViewControl x:Name="MainCarouselView" Grid.Row="0" Grid.ColumnSpan="3" Position="{Binding PositionIndex, Mode=TwoWay}">
<controls:CarouselViewControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding .}"></Image>
</DataTemplate>
</controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl >
And kept the cs code same. Thanks for the help guys.
Use CarouselView control for Xamarin Forms
https://github.com/alexrainman/CarouselView
and be sure you are following these steps:
In your iOS and Android projects call:
MainActivity.cs :
CarouselView.FormsPlugin.Android.CarouselViewRenderer.Init();
AppDelegate.cs :
CarouselView.FormsPlugin.iOS.CarouselViewRenderer.Init();
On your XAML view
xmlns:cv="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"
You shoudn't use Xamarin.Forms.CarouselView plugin, as it's hasn't been updated for years...For those interested, it was supposed to be an optimised successor of the CarouselPage - you can read more about it from James' blog post. For some reason it has been completely abandoned by Xamarin.Forms team.
Currently the best solution is to use Alex's Rainman CarouselView.FormsPlugin plugin, which is just great! However, I think currently it has some issues with supporting Xamarin.Forms 3.5 (github issue)
NOTE: Depending on what exactly you want to achieve, you might want to have a look at the Sharpnado's HorizontalListView carousel layout, which I'm almost certain is based off of the Alex's package.
For the future, keep an eye on the CollectionView, which will be a base for the brand new CarouselView in the Xamarin.Forms 4.0. You can read a bit more about it (and see a preview) in this blog post
NOTE: Please avoid using CarouselPage as well as the Xamarin.Forms.CarouselView
The CarouselPage does not support UI virtualization. Therefore, performance may be affected if the CarouselPage contains too many child elements.

Xamarin Forms ListView Scroll position - MVVM

I'm searching about this article for weeks!
UPDATE
Is controlling Listview scroll position in xamarin forms with MVVM pattern possible or not? getting and setting the scroll position of listview.
There are some answers like implementing event aggregation or using messaging or ... .
Neither of them weren't operating for me. The messaging is not fully MVVM pattern way. The event aggregation didn't work even I'm using prism 7.
There is no such a good example code or any nuget package.
Has anyone encountered this problem and solved it?
CustomersViewModel
public ObservableCollection<Customer> Customers {get;set;}
public Func<Customer,Task> ScrollToCustomer {get;set;}
public DelegateCommand FindBestCustomer {get;set;} // For example
FindBestCustomer = new DelegateCommand(async() =>
{
Customer bestCustomer = Customers.Last(); // this is our logic in view model!
await ScrollToCustomer(bestCustomer);
// at this time, scroll is finished.
});
CustomersView.xaml
<StackLayout>
<ListView x:Name="CustomersListView" ItemsSource={Binding Customers} />
<Button Text="Go to last customer" Command="{Binding ScrollToLastCustomer}" /> // For example
</StackLayout>
CustomersView.xaml.cs
override OnBindingContextChanged()
{
if(BindingContext is CustomersViewModel customersViewModel)
{
customersViewModel.ScrollToCustomer = customer => CustomersListView.ScrollTo(customer);
}
}

Separate UI for iPhone and iPad in Xamarin.Forms using xaml

I have been working on a Xamarin.Forms application that supports iOS and Android platforms. The UI has been build mostly using XAML in the Forms PCL project. I know it is possible through code using
if(Device.OS == TargetPlatform.iOS && Device.Idiom == TargetIdiom.Tablet)
How is it possible to build a new UI for iPad through XAML?
You can use the Idiom value OnIdiom in xaml:
<Grid VerticalOptions="FillAndExpand">
<Grid.ColumnSpacing>
<OnIdiom x:TypeArguments="x:Double"
Phone="20"
Tablet="40"/>
</Grid.ColumnSpacing>
</Grid>
With this, you can have different values in the xaml for phones or tablets.
When your design for your page are very different for phone and tablets, you better implement two different pages and navigate to the right one, with the idom-code you post in your question:
if (Device.Idiom == TargetIdiom.Tablet || Device.Idiom == TargetIdiom.Desktop)
await Navigation.PushAsync(new TabletPage());
else
await Navigation.PushAsync(new Page());
Look at this blog post from James Montemagno, which describes your problem exactly.
*Edit: Switching between 2 ContentViews based on the idiom can be done in the exact same way:
XAML:
<ContentPage x:Name="MyPage"></ContentPage>
Code-behind:
if (Device.Idiom == TargetIdiom.Tablet || Device.Idiom == TargetIdiom.Desktop)
MyPage.Content = new LargeDisplayContentView();
else
MyPage.Content = new SmallDisplayContentView();

Categories

Resources