简体   繁体   English

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

[英]Retrieving ListView selected item value in Xamarin.Forms

I'm developing/learning XamarinForms.我正在开发/学习 XamarinForms。 I'm using Web Api to get values and use them to populate a ListView.我正在使用 Web Api 来获取值并使用它们来填充 ListView。 Now I want to get current values on ItemSelected and store them for later use, but I don't seem to work it out.现在我想获取 ItemSelected 的当前值并存储它们以备后用,但我似乎没有解决。 I'm using the MVVM.我正在使用 MVVM。

This is my 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>

This is the 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);
        });
    }
}

And this is my API request这是我的 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;
}

And this is the Model这是模型

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

In your xaml add the ItemTapped property.在您的xaml添加ItemTapped属性。 Can be:可:

ItemTapped="ProfileDetails_Selected"

Then you should have the method handling the event in your code behind as:然后你应该让方法处理你的代码中的事件,如下所示:

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

Answer from Oluwasayo is correct but I see that you are using MVVM already so using this solution might be better for you, just in case if you want to keep your code-behind class clean and leave any mixing code-behind and ViewModel code for one functionality. Oluwasayo 的回答是正确的,但我看到您已经在使用 MVVM,因此使用此解决方案可能对您更好,以防万一您想保持代码隐藏类干净并留下任何混合代码隐藏和 ViewModel 代码功能。

I don't know if you are using some MVVM framework or not, but there is a very nice and helpful behavior called EventToCommandBehavior you can use it to "translate" any event and bind it to a command in your ViewModel.我不知道您是否正在使用某些 MVVM 框架,但是有一个非常好的和有用的behavior称为EventToCommandBehavior您可以使用它来“翻译”任何事件并将其绑定到 ViewModel 中的命令。

You can find implementation of it here on GitHub, you can easly include it in your project.你可以找到实现它在这里GitHub上,你可以伊斯利包括在您的项目。 There is a lot of other implementations from MVVM frameworks. MVVM 框架还有很多其他实现。

Steps to make this in the way I advice you are:按照我建议的方式完成此操作的步骤是:

  1. Include that class in your project and you can use it in xaml pages.在您的项目中包含该类,您可以在 xaml 页面中使用它。

  2. Edit VM code and add some aditional lines of code.编辑 VM 代码并添加一些额外的代码行。

ViewModel code:视图模型代码:

// 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. Edit your XAML page code and add few code lines.编辑您的 XAML 页面代码并添加几行代码。

XAML Page: 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>

Hope that this makes sense to you, using this approach your code-behind class will stay clean without mixing the code between vm and code-behind, just my tip for you.希望这对您有意义,使用这种方法您的代码隐藏类将保持干净,而不会在 vm 和代码隐藏之间混合代码,这只是我给您的提示。

Wishing you lots of luck with coding!祝你编码好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM