在Xamarin.Forms中检索ListView所选项目值

时间:2018-06-08 20:28:02

标签: c# rest api xamarin xamarin.forms

我正在开发/学习XamarinForms。我正在使用Web Api来获取值并使用它们来填充ListView。现在我想在ItemSelected上获取当前值并将它们存储起来供以后使用,但我似乎没有解决它。我正在使用MVVM。

这是我的ListView

<ListView x:Name="ProfileDetails" ItemsSource="{Binding Profiles}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout  Margin="20,0,0,0" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                     <Label Text="{Binding ProfileType}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" TextColor="LightGray"/>
                    <Label Text="{Binding ProfileChamber}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"  TextColor="LightGray"/>
                    <Label Text="{Binding ProfileWidhtMM}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" TextColor="LightGray"/>
                    <Label Text="{Binding ProfilePrice}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"  TextColor="LightGray"/>
                 </StackLayout>
             </ViewCell>
         </DataTemplate>
     </ListView.ItemTemplate>                
 </ListView>

这是ViewModel

APIServices _apiServices = new APIServices();


private List<Profile> _profiles;

public List<Profile> Profiles
{
    get { return _profiles; }
    set
    {
        _profiles = value;
        OnPropertyChanged();
    }
}


public ICommand GetProfilesCommand
{
    get
    {
        return new Command(async () =>
        {
            Profiles = await _apiServices.GetProfilesAsync(_accessToken);
        });
    }
}

这是我的API请求

public async Task<List<Profile>> GetProfilesAsync(string accessToken)
{
    var client = new HttpClient();

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    var json = await client.GetStringAsync(Constants.GetProfilesUrl);
    var profiles = JsonConvert.DeserializeObject<List<Profile>>(json);
    return profiles;
}

这是模型

public long Id { get; set; }
public string ProfileType { get; set; }
public int ProfileChamber { get; set; }
public int ProfileWidhtMM { get; set; }
public double ProfilePrice { get; set; } 

2 个答案:

答案 0 :(得分:0)

xaml添加ItemTapped媒体资源。可以是:

ItemTapped="ProfileDetails_Selected"

然后你应该在你的代码中处理事件的方法为:

private void ProfileDetails_Selected(object sender, ItemTappedEventArgs e)
    {
       var myItem = e.Item ...; //from here you can get your item and store for later use
    }

答案 1 :(得分:0)

来自Oluwasayo的回答是正确的,但我发现你已经在使用MVVM了,所以使用这个解决方案对你来说可能更好,以防万一你想保持你的代码隐藏类干净并留下任何混合代码隐藏和ViewModel一个功能的代码。

我不知道您是否使用了某些MVVM框架,但有一个非常好用且有用的behavior名为EventToCommandBehavior,您可以将其用于&#34;翻译&# 34;任何事件并将其绑定到ViewModel中的命令。

您可以在GitHub上找到它here的实现,您可以轻松地将它包含在您的项目中。 MVVM框架还有很多其他实现。

按照我建议的方式做到这一点的步骤是:

  1. 在项目中包含该类,您可以在xaml页面中使用它。

  2. 编辑VM代码并添加一些附加的代码行。

  3. ViewModel代码:

    // Property for binding SelectedItem from ListView.
    private Profile _selectedProfile;
    public Profile SelectedProfile
    {
        get { return _profiles; }
        set
        {
            _selectedProfile= value;
            OnPropertyChanged();
        }
    }
    
    // Command which we will use for Event to Command binding.
    public DelegateCommand ItemTappedCommand{ get; private set; }
    
    // ...
    // Code inside of the ctor in VM:
    ItemTappedCommand = new Command(ItemTapped);
    // ...
    
    // Method which will be executed using our command
    void ItemTapped()
    {
        // Here you can do whatever you want, this will be executed when
        // user clicks on item in ListView, you will have a value of tapped
        // item in SlectedProfile property
    }
    
    1. 编辑您的XAML页面代码并添加几行代码。
    2. XAML页面:

      <!-- In your page xaml header add xaml namespace to EventToCommandBehaviour class-->
      xmlns:b="clr-namespace:Namespace.ToYour.EventToCommandBehaviourClass"
      
      <ListView x:Name="ProfileDetails" ItemsSource="{Binding Profiles}"
                SelectedItem={Binding SelectedProfile}>
          <ListView.ItemTemplate>
              <DataTemplate>
                  <ViewCell>
                      <StackLayout Margin="20,0,0,0" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                          <Label Text="{Binding ProfileType}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" TextColor="LightGray"/>
                          <Label Text="{Binding ProfileChamber}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"  TextColor="LightGray"/>
                          <Label Text="{Binding ProfileWidhtMM}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" TextColor="LightGray"/>
                          <Label Text="{Binding ProfilePrice}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"  TextColor="LightGray"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
          </ListView.ItemTemplate>
          <ListView.Behaviors>
              <b:EventToCommandBehavior EventName="ItemTapped" 
                                        Command="{Binding ItemTappedCommand}" />
          </ListView.Behaviors>               
      </ListView>
      

      希望这对您有意义,使用这种方法,您的代码隐藏类将保持干净,而不会在vm和代码隐藏之间混合代码,只是我的提示。

      祝你编码好运!