The problem to be solved
The solution
The solution to this is simple, just hook up to the ItemSelected event for the ListView and set the SelectedItem property to null.
So the short version of you quick-googlers would be the following line of code. (in the View)
//Resettheselecteditemtomakeitselectable again
duckListView.ItemSelected+=(s,e)=>{
duckListView.SelectedItem=null;
And the navigation should be done in the ViewModel
publicDuckSelectedDuck
{
set
{
if(value !=null)
{
//IoComitted,weshouldreallygetsomeoneelseto
//createtheseobjectsforus.
varviewModel=newDuckViewModel(){ Duck =value};
varpage=newDuckView(viewModel);
_navigation.PushAsync(page);
}
}
}
The more verbose version
You could also navigate directly from this event handler, but you should feel it deep in your heart that that is just wrong. Instead we handle navigation in the ViewModel. I’ve created a sample project to do this. Also, I’m doing this without any additional framework that would handle navigation for you so that’s why I need to provide my ViewModel with a navigation interface.
I’ll present each file to you below or just download the sample solution from here.
The Model
{
publicstringName
{
get;
set;
}
}
The ViewModel (s)
We’ve got two ViewModels, but it’s really only the MainViewModel that’s interesting. It initializes it’s own data, which usually should be done async from another source. It doesn’t implement INotifyPropertyChanged either, as is should but for this sample it’s good enough.
What to focus on is the SelectedDuck property that handles the navigation. We only implement a setter for this since we reset the selected item anyhow in the view itself and on top of that navigate away from the page.
///<summary>
/// The sample ViewModel. Should implement INotifyPropertyChanged
///</summary>
publicclassMainViewModel
{
privateINavigation_navigation;
publicMainViewModel(INavigationnavigation)
{
_navigation=navigation;
Ducks=newList<Duck>()
{
newDuck(){ Name =“George“},
newDuck(){ Name =“Bob“},
newDuck(){ Name =“Sarah“},
newDuck(){ Name =“Clint“},
};
}
///<summary>
/// A list of ducks
///</summary>
///<value>The ducks.</value>
publicList<Duck>Ducks
{
get;
set;
}
publicDuckSelectedDuck
{
set
{
if(value !=null)
{
//IoComitted,weshouldreallygetsomeoneelseto
//createtheseobjectsforus.
varviewModel=newDuckViewModel(){ Duck =value};
varpage=newDuckView(viewModel);
_navigation.PushAsync(page);
}
}
}
}
The other ViewModel (DuckViewModel) simply references the selected duck on the page we navigate to.
publicclassDuckViewModel
{
publicDuckViewModel()
{
}
publicDuckDuck
{
get;
set;
}
}
The View
{
publicMainView()
{
InitializeComponent();
BindingContext=newMainViewModel(this.Navigation);//Shouldbe injected
//Resettheselecteditemtomakeitselectable again
duckListView.ItemSelected+=(s,e)=>{
duckListView.SelectedItem=null;
};
}
}
<ContentPagexmlns=“http://xamarin.com/schemas/2014/forms“xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml“x:Class=“ListViewNavigation.MainView“>
<ContentPage.Content>
<ListViewx:Name=“duckListView“
IsGroupingEnabled=“false“
ItemsSource=“{BindingDucks}“
HasUnevenRows=“true“
SelectedItem=“{BindingSelectedDuck}“>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<LabelFont=“Large“Text=“{BindingName}“/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
Summary
Please give feedback what ever you feel like! And if there’s a better way, I would love for you to enlighten me! 😀