Reputation: 5456
In our edit page, we have an issue to populate the value into Selected Item in picker and it won't select for some reason from the LoadCourses() or LoadRoundCategories() either.
Any ideas?
Here's the code:
ViewModel
public class EditGolfRoundViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
private string _message;
private ObservableCollection<GolfCourse> _courses;
private ObservableCollection<GolfRoundCategory> _roundCategories;
private object_selectedGolfCourse;
private GolfRoundCategory _selectedGolfRoundCategory;
private GolfRound _golfRound;
public EditGolfRoundViewModel()
{
_selectedGolfCourse = new GolfCourse();
_selectedGolfRoundCategory = new GolfRoundCategory();
LoadCourses();
LoadRoundCategories();
}
public GolfRound GolfRound
{
get { return _golfRound; }
set
{
_golfRound = value;
OnPropertyChanged();
}
}
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged();
}
}
public ObservableCollection<GolfCourse> GolfCourses
{
get { return _courses; }
set
{
if (_courses != value)
{
_courses = value;
OnPropertyChanged();
}
}
}
public ObservableCollection<GolfRoundCategory> GolfRoundCategories
{
get { return _roundCategories; }
set
{
_roundCategories = value;
OnPropertyChanged();
}
}
public object SelectedGolfCourse
{
get { return _selectedGolfCourse; }
set
{
_selectedGolfCourse = value;
var golfCourse = _selectedGolfCourse as GolfCourse;
Guid tempGolfCourseID = golfCourse.GolfCourseID;
OnPropertyChanged("SelectedGolfCourse");
}
}
public GolfRoundCategory SelectedGolfRoundCategory
{
get { return _selectedGolfRoundCategory; }
set
{
_selectedGolfRoundCategory = value;
OnPropertyChanged();
}
}
public ICommand EditCommand
{
get
{
return new Command(async() =>
{
GolfRound.GolfCourseID = SelectedGolfCourse.GolfCourseID;
GolfRound.GolfCourse = SelectedGolfCourse;
GolfRound.GolfRoundCategoryID = SelectedGolfRoundCategory.GolfRoundCategoryID;
GolfRound.GolfRoundCategory = SelectedGolfRoundCategory;
GolfRound.LastModifiedUTC = System.DateTime.Now;
await _apiServices.PutGolfRoundAsync(GolfRound, Settings.AccessToken);
});
}
}
public ICommand DeleteCommand
{
get
{
return new Command(async () =>
{
await _apiServices.DeleteGolfRoundAsync(GolfRound.GolfRoundID, Settings.AccessToken);
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private async void LoadCourses()
{
GolfCourses = new ObservableCollection<GolfCourse>(await _apiServices.GetGolfCoursesAsync(Settings.AccessToken));
}
private async void LoadRoundCategories()
{
GolfRoundCategories = new ObservableCollection<GolfRoundCategory>(await _apiServices.GetGolfRoundCategoriesAsync(Settings.AccessToken));
}
}
View - XAML
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:AthlosifyMobile.ViewModels.Golf"
x:Class="AthlosifyMobile.Views.EditGolfRoundPage">
<StackLayout Orientation="Vertical" VerticalOptions="Center" Spacing="30" Padding="30">
<Entry Text="{Binding GolfRound.Name}" Placeholder="name" FontSize="Default" />
<Entry Text="{Binding GolfRound.Notes}" Placeholder="notes" FontSize="Default" />
<Entry Text="{Binding GolfRound.DailyHandicap}" Placeholder="daily handicap" FontSize="Default" />
<Label Text="Date" />
<DatePicker Date="{Binding GolfRound.TeeOffUTC}"
Format="D"
Margin="30, 0, 0, 30" />
<Picker x:Name="pCourse" Title="Course" ItemsSource="{Binding GolfCourses}"
SelectedItem="{Binding SelectedGolfCourse, Mode=TwoWay}"
ItemDisplayBinding="{Binding Name}"></Picker>
<Entry Text="{Binding GolfRound.GolfCourse.Name}" Placeholder="selected golf course" FontSize="Default" />
<Picker x:Name="pCategory" Title="Category" ItemsSource="{Binding GolfRoundCategories}"
SelectedItem="{Binding SelectedGolfRoundCategory, Mode=TwoWay}"
ItemDisplayBinding="{Binding Name}"></Picker>
<Entry Text="{Binding SelectedGolfRoundCategory.Name}" Placeholder="selected round category" FontSize="Default" />
<Button Command="{Binding EditCommand}" Text="Edit Round" />
<Button Command="{Binding DeleteCommand}" Text="Delete Round" />
<Label Text="{Binding Message}" ></Label>
</StackLayout>
View - code behind
public partial class EditGolfRoundPage : ContentPage
{
public EditGolfRoundPage (GolfRound round)
{
var editGolfRoundViewModel = new EditGolfRoundViewModel();
editGolfRoundViewModel.GolfRound = round;
BindingContext = editGolfRoundViewModel;
InitializeComponent ();
//var editGolfRoundViewModel = new EditGolfRoundViewModel();
//editGolfRoundViewModel.GolfRound = round;
//editGolfRoundViewModel.SelectedGolfCourse = round.GolfCourse;
//BindingContext = editGolfRoundViewModel;
}
}
Upvotes: 11
Views: 9746
Reputation: 726
The following is true as of Xamarin Forms v4.7.
See if you are doing this:
<Picker x:Name="DefaultEntitlement" Title="Entitlement"
SelectedItem="{Binding SelectedOwnerEntitlement, Mode=TwoWay}"
ItemsSource="{Binding OwnerEntitlements, Mode=TwoWay}">
</Picker>
Instead of this:
<Picker x:Name="DefaultEntitlement" Title="Entitlement"
ItemsSource="{Binding OwnerEntitlements, Mode=TwoWay}"
SelectedItem="{Binding SelectedOwnerEntitlement, Mode=TwoWay}">
</Picker>
Upvotes: 9
Reputation: 3775
You can try:
INotifyPropertyChanged
Selected Item
variable has initial valueselected item
variable, make sure has value1. Initials
Take a look your code:
public EditGolfRoundViewModel()
{
_selectedGolfCourse = new GolfCourse();
_selectedGolfRoundCategory = new GolfRoundCategory();
LoadCourses();
LoadRoundCategories();
}
If you try to initial value Selected Item
, don't do this:
_selectedGolfCourse = new GolfCourse();
_selectedGolfRoundCategory = new GolfRoundCategory();
let it null
, is fine. You can do like this:
SelectedGolfRoundCategory = new GolfRoundCategory();
//or
SelectedGolfRoundCategory = dataFromAPI;
2. Assign
Take a look your code:
public ICommand EditCommand
{
get
{
return new Command(async() =>
{
GolfRound.GolfCourseID = SelectedGolfCourse.GolfCourseID;
GolfRound.GolfCourse = SelectedGolfCourse;
GolfRound.GolfRoundCategoryID = SelectedGolfRoundCategory.GolfRoundCategoryID;
GolfRound.GolfRoundCategory = SelectedGolfRoundCategory;
GolfRound.LastModifiedUTC = System.DateTime.Now;
await _apiServices.PutGolfRoundAsync(GolfRound, Settings.AccessToken);
});
}
}
You trying selected item
variable insert into to object GolfRound
, like this part:
GolfRound.GolfRoundCategoryID = SelectedGolfRoundCategory.GolfRoundCategoryID;
GolfRound.GolfRoundCategory = SelectedGolfRoundCategory;
Make sure you have INotifyPropertyChanged
implement this model GolfRound
for prop GolfRoundCategoryID
and GolfRoundCategory
. If not, it would not work. I have experience for this.
Hope this helpful.
Upvotes: 0
Reputation: 2943
Can you try once replacing your Viewmodel. I have changed the type from Object to actual type. Set the Default item while loading the items from endpoint.
public class EditGolfRoundViewModel : INotifyPropertyChanged
{
ApiServices _apiServices = new ApiServices();
private string _message;
private ObservableCollection<GolfCourse> _courses;
private ObservableCollection<GolfRoundCategory> _roundCategories;
private GolfCourse _selectedGolfCourse;
private GolfRoundCategory _selectedGolfRoundCategory;
private GolfRound _golfRound;
public EditGolfRoundViewModel()
{
LoadCourses();
LoadRoundCategories();
}
public GolfRound GolfRound
{
get { return _golfRound; }
set
{
_golfRound = value;
OnPropertyChanged();
}
}
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged();
}
}
public ObservableCollection<GolfCourse> GolfCourses
{
get { return _courses; }
set
{
if (_courses != value)
{
_courses = value;
OnPropertyChanged();
}
}
}
public ObservableCollection<GolfRoundCategory> GolfRoundCategories
{
get { return _roundCategories; }
set
{
_roundCategories = value;
OnPropertyChanged();
}
}
public GolfCourse SelectedGolfCourse
{
get { return _selectedGolfCourse; }
set
{
_selectedGolfCourse = value;
OnPropertyChanged("SelectedGolfCourse");
}
}
public GolfRoundCategory SelectedGolfRoundCategory
{
get { return _selectedGolfRoundCategory; }
set
{
_selectedGolfRoundCategory = value;
OnPropertyChanged();
}
}
public ICommand EditCommand
{
get
{
return new Command(async () =>
{
GolfRound.GolfCourseID = SelectedGolfCourse.GolfCourseID;
GolfRound.GolfCourse = SelectedGolfCourse;
GolfRound.GolfRoundCategoryID = SelectedGolfRoundCategory.GolfRoundCategoryID;
GolfRound.GolfRoundCategory = SelectedGolfRoundCategory;
GolfRound.LastModifiedUTC = System.DateTime.Now;
await _apiServices.PutGolfRoundAsync(GolfRound, Settings.AccessToken);
});
}
}
public ICommand DeleteCommand
{
get
{
return new Command(async () =>
{
await _apiServices.DeleteGolfRoundAsync(GolfRound.GolfRoundID, Settings.AccessToken);
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private async void LoadCourses()
{
GolfCourses = new ObservableCollection<GolfCourse>(await _apiServices.GetGolfCoursesAsync(Settings.AccessToken));
if (GolfCourses != null && GolfCourses.Count() > 0)
SelectedGolfCourse = GolfCourses[0];
}
private async void LoadRoundCategories()
{
GolfRoundCategories = new ObservableCollection<GolfRoundCategory>(await _apiServices.GetGolfRoundCategoriesAsync(Settings.AccessToken));
if (GolfRoundCategories != null && GolfRoundCategories.Count() > 0)
SelectedGolfRoundCategory = GolfRoundCategories[0];
}
}
Upvotes: 0
Reputation: 2995
Implement IEquatable
for class of property used in SelectedItem
:
public class GolfCourse : IEquatable<GolfCourse>
{
...
public bool Equals(GolfCourse other)
{
if (other == null) return false;
return (this.Name.Equals(other.Name));
}
}
Usage, assuming ItemsSource
contains an object with value of Name
as shown below:
SelectedGolfCourse = new GolfCourse { Name = "Course 2" };
Upvotes: 21
Reputation: 980
Xaml
<Picker x:Name="ProductPicker" WidthRequest="220" HeightRequest="35" Title="Select" ItemsSource="{Binding ProductList}" SelectedItem="{Binding ProductSelected}" ItemDisplayBinding="{Binding ProductName}"> </Picker>
ViewModel
public List<ProductModel> ProductList { get; set; }
Populating Data in Datasource in Viewmodel
ProductList = Products.Result.ToList();
Getting Selected Data
private object _ProductSelected;
public object ProductSelected
{
get { return _ProductSelected; }
set
{
_ProductSelected = value;
ProductSelected_SelectedIndex.Execute(value);
OnPropertyChanged("ProductSelected"); //in case you are using MVVM Light
}
}
private Command ProductSelected_SelectedIndex
{
get
{
return new Command((e) =>
{
}}}
private object _CitySelectedFromList;
public object CitySelectedFromList
{
get { return _CitySelectedFromList; }
set
{
_CitySelectedFromList = value;
var cityid = _CitySelectedFromList as CityMasterModel;
tempcityids = Convert.ToInt32(cityid.Id);
}
}
Upvotes: 0
Reputation: 144
you are binding view model before Initialise page so that is wrong thing we can not bind data without Initialise page fro that you need to change code of xaml.cs like below
public EditGolfRoundPage (GolfRound round)
{
InitializeComponent ();
BindingContext = editGolfRoundViewModel;
BindingContext.GolfRound = round;
}
that will work for you Happy Coding :)
Upvotes: 0