Reputation: 725
I am trying to get a picker to populate with data. There doesn't seem to be a straight answer anywhere on this. I have tried numerous things, one thing that does work is :
Xaml:
<Picker Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="4"
Title="Driver Name"
ItemsSource="{Binding Drivers}"
SelectedItem="{Binding driverID}"
and in the View Model:
List<string> Drivers = new List<string> { "Steve","Dave" };
This works fine, but its just a dummy capability as in the future these names will be grabbed from a service of some kind. So in an attempt to copy this I tried separating this list into a mock service and just returning the list to the view model and making it work that way.
But this still returns nothing to the front end even though I can see that the list is not blank when debugging. Then I tried to create a class of Driver and return instances of the class that has the name in it and access it in the Xaml. This did not work, I even tried a variation using IList, this did not work either.
I am not sure why this does not work as the list was just separated to essentially a different class. For instance this is what I am trying now:
Xaml:
<Picker Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="4"
Title="Driver Name"
ItemsSource="{Binding Drivers}"
SelectedItem="{Binding driverID}"
/>
View Model:
This is bound to the picker
public List<string> Drivers;
Then this method is called from the constructor:
public async Task FindDriverNames()
{
Drivers = await GetDriverNames();
}
and in the Model:
public async Task<List<string>> GetDriverNames()
{
await Sleep();
List<string> _drivers = new List<string> { "Steve"};
return _drivers;
}
This does not work, but when run through debug it shows that Drivers is populated. I have wasted a lot of time trying to get this work, does anyone have insights?
Upvotes: 3
Views: 4129
Reputation: 17678
You'll need an ObservableCollection
, and possibly a INotifyPropertyChanged
interface implementation to notify the view for any changes.
public class YourViewModel: INotifyPropertyChanged
{
public YourViewModel()
{
Drivers = new ObservableCollection<string>();
}
private ObservableCollection<string> _drivers;
public ObservableCollection<string> Drivers
{
get { return _drivers; }
set
{
if (Equals(value, _drivers)) return;
_drivers= value;
OnPropertyChanged(nameof(Drivers));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
By implementing the INotifyPropertyChanged
interface, you will allow the view to be updated whenever the whole list changes. The observable collection will notify the UI if a item is added to the collection.
As noted by Roman, youo can also, in this specific case use the observable collection to update the ui
.
public async Task FindDriverNames()
{
Drivers.Clear();
Drivers.AddRange(await GetDriverNames());
}
For other bound
properties you'll still need the OnPropertyChanged
event.
See ObservableCollection<T> and INotifyPropertyChanged
Upvotes: 2