When I add or remove items from my ObservableCollection that is used as the ItemSource for a SlideView, I get the following error:
"System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"
Is there some specific process I should be following when adding/removing items from the bound ObservableCollection for a SlideView that is already rendered?
17 Answers, 1 is accepted

Here's my viewmodel:
public class Photo : INotifyPropertyChanged
{
public string FileName
{
get => FileName;
set
{
FileName = value;
OnPropertyChanged("FileName");
}
}
public long DateTime
{
get => DateTime;
set
{
DateTime = value;
OnPropertyChanged("DateTime");
}
}
public Photo(string filename, long dateTime)
{
FileName = filename;
DateTime = dateTime;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In my form constructor:
_photos = new ObservableCollection<
Photo
>();
SlideViewPhotos.ItemsSource = _photos;
And in my XAML:
<
primitives:RadSlideView
x:Name
=
"SlideViewPhotos"
HeightRequest
=
"360"
Padding
=
"0,15,0,0"
IsInfiniteScrollingEnabled
=
"True"
>
<
primitives:RadSlideView.ItemTemplate
>
<
DataTemplate
>
<
ContentView
>
<
Grid
WidthRequest
=
"200"
>
<
Image
Source
=
"{Binding FileName}"
Margin
=
"0,0,0,50"
/>
</
Grid
>
</
ContentView
>
</
DataTemplate
>
</
primitives:RadSlideView.ItemTemplate
>
</
primitives:RadSlideView
>
I am not able to replicate what you're seeing, here's an animated GIF of my test at runtime:
Here's the code:
<
ContentPage
...>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
/>
<
RowDefinition
Height
=
"Auto"
/>
</
Grid.RowDefinitions
>
<
telerikPrimitives:RadSlideView
x:Name
=
"slideView"
>
<
telerikPrimitives:RadSlideView.ItemTemplate
>
<
DataTemplate
>
<
ContentView
>
<
Label
Text
=
"{Binding DisplayText}"
TextColor
=
"#007ACC"
HorizontalTextAlignment
=
"Center"
/>
</
ContentView
>
</
DataTemplate
>
</
telerikPrimitives:RadSlideView.ItemTemplate
>
</
telerikPrimitives:RadSlideView
>
<
StackLayout
Orientation
=
"Horizontal"
Grid.Row
=
"1"
>
<
Button
x:Name
=
"AddButton"
Text
=
"Add Item"
Clicked
=
"AddButton_OnClicked"
/>
<
Button
x:Name
=
"RemoveButton"
Text
=
"Remove Last Item"
Clicked
=
"RemoveButton_OnClicked"
/>
</
StackLayout
>
</
Grid
>
</
ContentPage
>
namespace
DynamicItems.Portable
{
public
partial
class
StartPage : ContentPage
{
public
StartPage()
{
InitializeComponent();
slideView.ItemsSource = MySlideViewItems;
}
public
ObservableCollection<MyItemModel> MySlideViewItems {
get
; } =
new
ObservableCollection<MyItemModel>
{
new
MyItemModel { DisplayText =
"Item 1"
},
new
MyItemModel { DisplayText =
"Item 2"
},
new
MyItemModel { DisplayText =
"Item 3"
}
};
private
void
AddButton_OnClicked(
object
sender, EventArgs e)
{
MySlideViewItems.Add(
new
MyItemModel { DisplayText = $
"Item {MySlideViewItems.Count + 1} (added)"
});
}
private
void
RemoveButton_OnClicked(
object
sender, EventArgs e)
{
MySlideViewItems.Remove(MySlideViewItems.LastOrDefault());
}
}
public
class
MyItemModel
{
public
string
DisplayText {
get
;
set
; }
}
}
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik



I noticed you have syntax error in your data model, your property accessors are recursive.
The highlighted code below will infinitely reference itself when you first try to show the FileName and cause an exception
public
class
Photo : INotifyPropertyChanged
{
public
string
FileName
{
get
=> FileName;
set
{
FileName = value;
OnPropertyChanged(
"FileName"
);
}
}
}
If you're not familiar with the new C# Expression Body syntax "=>", it's the same as doing this:
public
string
FileName
{
get
{
return
FileName;
}
}
Now you can see the recursion easier. If you get FileName, it will get FileName infinitely.
Fix
To fix this, use a property backing field,:
private
string
_fileName;
public
string
FileName
{
get
=> _fileName;
set
{
_fileName = value;
OnPropertyChanged();
}
}
Also to prevent multiple UI bindings, which can lead to flickering an unnecessary updates, don't call OnPropertyChanged unless the value is updated.
private
string
_fileName;
public
string
FileName
{
get
=> _fileName;
set
{
if
(_fileName == value)
return
;
_fileName = value;
OnPropertyChanged();
}
}
Lastly, I strongly discourage you from using a property name of "DateTime" because it's a C# type already. Try something like "Timestamp" instead
private
long
_timestamp;
public
long
Timestamp
{
get
=> _timestamp;
set
{
if
(_timestamp == value)
return
;
_timestamp = value;
OnPropertyChanged();
}
}
Complete Updated Model
Here is the complete, refactored model (you do not need to change other code because the class instantiates the same)
public
class
Photo : INotifyPropertyChanged
{
// backing fields
private
string
_fileName;
private
long
_timestamp;
// constructor
public
Photo(
string
filename,
long
timestamp)
{
FileName = filename;
Timestamp = timestamp;
}
// Properties
public
string
FileName
{
get
=> _fileName;
set
{
if
(_fileName == value)
return
;
_fileName = value;
OnPropertyChanged();
}
}
public
long
Timestamp
{
get
=> _timestamp;
set
{
if
(_timestamp == value)
return
;
_timestamp = value;
OnPropertyChanged();
}
}
// Property Changed
public
event
PropertyChangedEventHandler PropertyChanged;
protected
virtual
void
OnPropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
PropertyChanged?.Invoke(
this
,
new
PropertyChangedEventArgs(propertyName));
}
}
After making that change, I was able to get your original code working.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik

Thanks for the recommendations. I made the changes, and the code works, however, I still have this exception when the MySlideView observable collection is initially empty:
"System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"

I tested this again and was not able to replicate the issue you're seeing, adding an item when the collection is empty works as expected in my test. Here is the relevant code:
public
partial
class
StartPage : ContentPage
{
private
readonly
ObservableCollection<Photo> _photos;
public
StartPage()
{
InitializeComponent();
_photos =
new
ObservableCollection<Photo>();
slideView.ItemsSource = _photos;
}
private
void
AddButton_OnClicked(
object
sender, EventArgs e)
{
_photos.Add(
new
Photo(
"Photo"
, 1234));
}
}
Are you sure you're using the latest version of UI for Xamarin? If you right click on any Telerik reference and select "Properties", you should see 2018.1.315 in the "Version" box.
Next Steps
So that I can get you a solution as fast as possible, can you please update my attached demo with your code so that it replicates the problem and send it back to me? With that, I'll be able directly debug it and determine the cause.
Once you're replicated it, you have two option s to get me the changes
Option 1:
Because this is a forum thread, you can't attach a ZIP. Instead you can use a file service (i.e. DropBox, OneDrive) and share the download link. Just be sure to delete the bin and obj folders from each project before zipping up the application, this will significantly reduce the file size).
Option 2:
Reply back using a code block for each class/page, like I did above for StartPage.xaml.cs. If you choose this option, please make sure to let me know all of the platform specifics (target platform, what SDK level did you choose, etc).
I look forward to your reply.
Side Note: During my investigation I did notice another issue, but it is unrelated to your problem. I've logged it here SlideView: Initial item not binding correctly.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik

I've tried a variety of order-of-operations (add 5 & remove 2 or add 6 & remove 4, etc), I was not able to get the buttons to stop working. after each different test, the button still navigate the remaining items in the SlideView.
Can you please run my demo (attached to my last reply) and see if your steps replicate the behavior.
- If you were able to reproduce it: Let me know the order of operations that you took so I can reproduce it on my side.
- If you are not able to reproduce it: The issue lies elsewhere in your application. In order me to help find you a solution, please share the rest of your code, or update my demo, so that I can reproduce it.
I understand and appreciate that it takes a little effort to put together a reproducible, however it's almost always the fastest way for me to get you to a solution (or workaround).
I look forward to your reply.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik

I downloaded you solution files and I was able to break it. Follow these steps:
1. Add 2 items
2. Press >
3. Press remove button
4. Add 1 item
5. Press >
6. Press remove button
7. Add 1 item
8. Press >
9. Press remove button
Notice that the remaining dot is no longer coloured, which indicates that it hasn't been selected. From this point onwards, any items added can not be navigated to using the < and > buttons.
Thank you for the steps. With that information, I was able to reproduce the issue with fewer steps and no items removed:
1- Add 2 items (Observe: bound content doesn't show the values after being added)
2 - Click right arrow (Observe: bound content now appears)
3 - Click left arrow (Observe: SlideView goes to 1st item)
4 - Observe: buttons no longer work
I have escalated this to the SlideView developers for further investigation, thank you for taking the time to help reproduce the issue.
Workaround
I've created a workaround for you to use in the meantime, see the updated demo attached. To summarize the workaround, we disabled the SlideView's buttons and replaced them with your own buttons:
- The SlideView has hidden buttons
- The left button has a left arrow
- The right button has a right arrow
<
Grid
x:Name
=
"SlideViewGrid"
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
Button
Text
=
"<"
Grid.Column
=
"0"
VerticalOptions
=
"Center"
Clicked
=
"LeftButton_OnClicked"
/>
<
telerikPrimitives:RadSlideView
x:Name
=
"slideView"
ShowButtons
=
"False"
Grid.Column
=
"1"
>
<
telerikPrimitives:RadSlideView.ItemTemplate
>
<
DataTemplate
>
<
ContentView
>
<
Label
Text
=
"{Binding FileName}"
TextColor
=
"#007ACC"
HorizontalTextAlignment
=
"Center"
/>
</
ContentView
>
</
DataTemplate
>
</
telerikPrimitives:RadSlideView.ItemTemplate
>
</
telerikPrimitives:RadSlideView
>
<
Button
Text=">"
Grid.Column="2"
VerticalOptions="Center"
Clicked="RightButton_OnClicked"/>
</
Grid
>
The button's click event increases or decreases the SelectedIndex, which will also provide the same visual effect as you'd get with the built-in buttons.
private
void
LeftButton_OnClicked(
object
sender, EventArgs e)
{
if
(slideView.SelectedIndex != 0)
{
slideView.SelectedIndex = slideView.SelectedIndex - 1;
}
else
{
// if you want "infinite scrolling", uncomment this
// slideView.SelectedIndex = _photos.Count - 1;
}
}
private
void
RightButton_OnClicked(
object
sender, EventArgs e)
{
if
(slideView.SelectedIndex < _photos.Count - 1)
{
slideView.SelectedIndex = slideView.SelectedIndex + 1;
}
else
{
// if you want "infinite scrolling", uncomment this
// slideView.SelectedIndex = 0;
}
}
NOTE: If you need infinite scrolling, just wrap the SelectedIndex back to the beginning/end of the indices (uncomment the lines above):
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
I wanted to follow up let you know that the developers have identified and fixed the problem. It will be included in an upcoming release (expected next week). I have updated your Telerik points for bringing this to our attention.
Thank you for your patience and understanding while we worked to resolve this.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik

I think the buttons not working is a symptom of a bigger problem. I have turned off the buttons and rely on the user to swipe left and right. If I swipe to the very right to see the last item (let's say item #4 for example), then push a delete button to delete that last item in the ObservableCollection, the RadSlideView updates correctly and now I see item #3, the SlidedIndex event fires with the correct SelectedIndex and the circle indicators show the correct dot. However, if I now try to swipe left to see Item #2, I see Item#2, but the circle indicators stay on item #3 and the SlidedIndex event fires but still says SelectedIndex is for Item #3 which I use to update my page title.
So in summary, deleting an item in the ObservableCollection ItemsSource of RadSlideView leaves the RadSlideView in an invalid state. You have to swipe a few times to get it back in sync.

Thank you for the detailed description.
I have quickly managed to reproduce the issue with the indicators and I confirm this is an issue on our side, I have logged in our Feedback Portal, you could follow the item at the link below:
https://feedback.telerik.com/Project/168/Feedback/Details/255062-slideview-ios-removing-an-item-from-the-itemssource-leaves-the-slideview-in-in
I am afraid there isn't a suitable workaround I could suggest.
I am sorry for the caused inconvenience.
Regards,
Yana
Progress Telerik