所选项目在Picker中不起作用

时间:2018-08-05 05:08:12

标签: c# xamarin mvvm xamarin.forms

在我们的编辑页面中,我们遇到一个问题,即将值填充到选择器中的“选定项”中,由于某种原因,它也不会从LoadCourses()或LoadRoundCategories()中进行选择。

有什么想法吗?

代码如下:

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));
    }

}

查看-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>

查看-后面的代码

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;

    }
}

6 个答案:

答案 0 :(得分:5)

SelectedItem中使用的属性类别实施IEquatable

public class GolfCourse : IEquatable<GolfCourse>
{
    ...
    public bool Equals(GolfCourse other)
    {
        if (other == null) return false;
        return (this.Name.Equals(other.Name));
    }
}

用法,假设ItemsSource包含一个值为Name的对象,如下所示:

SelectedGolfCourse = new GolfCourse { Name = "Course 2" };

答案 1 :(得分:4)

以下内容适用于Xamarin Forms v4.7。

看看您是否正在这样做:

<Picker x:Name="DefaultEntitlement" Title="Entitlement"
    SelectedItem="{Binding SelectedOwnerEntitlement, Mode=TwoWay}"
    ItemsSource="{Binding OwnerEntitlements, Mode=TwoWay}">
</Picker>

代替此:

<Picker x:Name="DefaultEntitlement" Title="Entitlement"
    ItemsSource="{Binding OwnerEntitlements, Mode=TwoWay}"
    SelectedItem="{Binding SelectedOwnerEntitlement, Mode=TwoWay}">
</Picker>

答案 2 :(得分:0)

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; }

在Viewmodel的数据源中填充数据

    ProductList = Products.Result.ToList();

获取所选数据

   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);

        }
    }

答案 3 :(得分:0)

您在初始化页面之前绑定了视图模型,所以这是错误的事情,我们无法在没有初始化页面的情况下绑定数据,因为您需要更改xaml.cs的代码,如下所示 public EditGolfRoundPage (GolfRound round) { InitializeComponent (); BindingContext = editGolfRoundViewModel; BindingContext.GolfRound = round; }

将为您服务 快乐编码:)

答案 4 :(得分:0)

可以一次更换Viewmodel吗?我已将类型从“对象”更改为实际类型。从端点加载项目时设置“默认”项目。

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];

}

}

答案 5 :(得分:0)

您可以尝试:

  • 确保您的道具支持INotifyPropertyChanged
  • 确保Selected Item变量具有初始值
  • 尝试调试您的selected item变量,确保它具有价值

1。缩写

看看您的代码:

public EditGolfRoundViewModel()
{
    _selectedGolfCourse = new GolfCourse();
    _selectedGolfRoundCategory = new GolfRoundCategory();
    LoadCourses();
    LoadRoundCategories();
}

如果您尝试将初始值设为Selected Item,请不要这样做:

_selectedGolfCourse = new GolfCourse();
_selectedGolfRoundCategory = new GolfRoundCategory();

将其设为null,就可以了。您可以这样:

SelectedGolfRoundCategory = new GolfRoundCategory();
//or
SelectedGolfRoundCategory = dataFromAPI;

2。分配

看看您的代码:

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);
        });
    }
 }

您尝试将selected item变量插入对象GolfRound中,就像下面这样:

  GolfRound.GolfRoundCategoryID = SelectedGolfRoundCategory.GolfRoundCategoryID;
  GolfRound.GolfRoundCategory = SelectedGolfRoundCategory;

确保已INotifyPropertyChanged为道具GolfRoundGolfRoundCategoryID实现此模型GolfRoundCategory。如果没有,那就行不通了。我对此有经验。

希望这会有所帮助。