[英]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:按照我建议的方式完成此操作的步骤是:
Include that class in your project and you can use it in xaml pages.在您的项目中包含该类,您可以在 xaml 页面中使用它。
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
}
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.