ListView ItemSelected打开详细信息页面MVVM
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ListView ItemSelected打开详细信息页面MVVM相关的知识,希望对你有一定的参考价值。
在学习xamarin的个人项目中工作,开始关注我从API获得的所选项目的详细页面。 API,它返回一个这样的数组:
{
"Restaurant": [
{
"Address": "Route Bounes Aires",
"RestaurantID": "1",
"RestaurantName": "John Doe",
"City": "Lorem Ipsum"
}
{
"Address": "Route Bounes Aires",
"RestaurantID": "2",
"RestaurantName": "John Doe",
"City": "Lorem Ipsum"
}]
我设法使用MVVM模式在列表视图中绑定这些信息。现在我似乎无法打开所选项目的详细页面。这是我到目前为止:restaurantviewmodel.cs
public class RestaurantViewModel : INotifyPropertyChanged
{
Service _services = new Service();
List<Restaurant> _restaurant;
public List<Restaurant> Restaurant
{
get { return _restaurant; }
set
{
if (value == _restaurant) return;
_branches = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand ReastaurantCommand
{
get
{
return new Command(async () =>
{
Reastaurant = await _apiServices.GetReastaurant();
await Application.Current.MainPage.Navigation.PushAsync(new ReastaurantPage(_restaurant));
});
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
service.cs
public async Task<List<Reastaurant>> GetReastaurant()
{
ListReastaurant restaurant = null;
try {
var client = new HttpClient();
client.DefaultRequestHeaders.Add("xxx", "xxx");
client.DefaultRequestHeaders.Add("xxx", xxx);
HttpContent content = new StringContent("");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync("https:www.here/goes/the/call/to/the/api", content);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
restaurant = JsonConvert.DeserializeObject<ListReataurantDetails>(json);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message.ToString());
}
return restaurant.Restaurant;
}
模型restaurant.cs
public class Restaurant
{
public string Address { get; set; }
public string restaurantID { get; set; }
public string RestaurantName { get; set; }
public string City { get; set; }
}
页面restaurant.xaml:
<ListView x:Name="restaurantlistview"
HasUnevenRows="True" ItemSelected="restaurantlistview_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20, 10">
<Label Text="{Binding RestaurantName}"
FontSize="20"
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
restaurant.xaml.cs背后的代码
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Restaurant : ContentPage
{
public Restaurant(List<Models.Restaurant> restaurant)
{
InitializeComponent();
NavigationPage.SetTitleIcon(this, "icon.png");
restaurantlistview.ItemsSource = restaurant;
}
private async void restaurantlistview_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
await Navigation.PushAsync(new RestaurantSinglePageDetails());
}
}
我该如何处理这个问题?我想将一家餐馆的详细信息用于另一页,这样我就可以显示地址和城市,并使用这些信息来做不同的事情。我认为很容易我没有很好地理解mvvm模式的概念。澄清我不是想把所有数据传递到另一个页面,而只是试图访问有关single item
(餐厅)的信息。我真的需要一些帮助。多谢你们!
===编辑===
public partial class RestaurantSinglePageDetails: ContentPage
{
public RestaurantSinglePageDetails(Models.Restaurant res)
{
InitializeComponent();
NavigationPage.SetTitleIcon(this, "logosmall.png");
BindingContext = new RestaurantDetailsViewModel(res);
//and here I'm supposed to have access to my selected restaurant.
}
}
餐厅详情viewmodel.cs
public class RestaurantDetailsViewModel : INotifyPropertyChanged
{
// ==edit==
Restaurant restaurant;
public RestaurantDetailsViewModel(Restaurant restaurant)
{
this.restaurant = restaurant; // now we can use it in ViewModel
}
Service _services = new Service();
List<Info> _info;
public List<Info> Info
{
get { return _info; }
set
{
if (value == _info) return;
_info = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetInfoCommand
{
get
{
return new Command(async () =>
{
InfoData = await _apiServices.GetInfoData();
await Application.Current.MainPage.Navigation.PushAsync(new SingleDetailsAboutPrice(InfoData, restaurant));
});
}
}
}
我想在这里使用RestaurantID:SingleDetailsAboutPrice.xaml.cs:
Restaurant restaurant;
public SingleDetailsAboutPrice(List<Models.InfoData> data, Restaurant restaurant)
{
InitializeComponent();
this.restaurant = restaurant;
//can't use the restaurantid here;
//some code goes here;
}
错误
给定的密钥不在字典中
在你的contentPage餐厅课你应该
的InitializeComponent();
在构造函数类中
XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Restaurant : ContentPage
{
public Restaurant(List<Models.Restaurant> restaurant)
{
InitializeComponent();
NavigationPage.SetTitleIcon(this, "icon.png");
restaurantlistview.ItemsSource = restaurant;
}
private async void restaurantlistview_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
//edit
var restaurant = (Restaurant)sender;
await Navigation.PushAsync(new RestaurantSinglePageDetails(restaurant));
}
}
获取您选择的项目:
var restaurant = (Restaurant)sender;
接下来你必须创建新的页面
public partial class RestaurantSinglePageDetails: ContentPage
{
Restaurant res;
public RestaurantSinglePageDetails(Restaurant res)
{
InitializeComponent();
this.res = res;
//and here you have access to your selected restaurant.
}
}
您可以访问所有班级。因此,当您移动到另一个页面时,您可以放置此res。
===编辑===
如果我的意思是正确的,你想将RestaurantID传递给SingleDetailsAboutPrice
所以你必须将它传递给RestaurantDetailsViewModel
and,然后如果你点击按钮将它传递给SingleDetailsAboutPrice(RestaurantId)
。
public partial class RestaurantSinglePageDetails: ContentPage
{
Restaurant res;
public RestaurantSinglePageDetails(Restaurant res)
{
InitializeComponent();
BindingContext = new RestaurantDetailsViewModel(item); //now you have access to restaurant in your viewModel. In this way you don't need use BindingContext in XAML
this.res = res;
//and here you have access to your selected restaurant.
}
}
现在在RestaurantDetailsViewModel
中我们需要用Restaurant
创建构造函数
public class RestaurantDetailsViewModel : INotifyPropertyChanged
{
Service _services = new Service();
Restaurant restaurant;
public RestaurantDetailsViewModel(Restaurant restaurant)
{
this.restaurant = restaurant; // now we can use it in ViewModel
}
List<Info> _info;
public List<Info> Info
{
get { return _info; }
set
{
if (value == _info) return;
_info = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand GetInfoCommand
{
get
{
return new Command(async () =>
{
InfoData = await _apiServices.GetInfoData();
await Application.Current.MainPage.Navigation.PushAsync(new SingleDetailsAboutPrice(restaurant)); // or if you want u can pass only restaurant.restaurantID.
});
}
}
}
在SingleDetailsAboutPrice
我们用Restaurant
或只有RestaurantId
创建构造函数
public partial class Restaurant : ContentPage
{
Restaurant restaurant;
public SingleDetailsAboutPrice(Restaurant restaurant)
{
InitializeComponent();
this.restaurant = restaurant;
}
String restaurantID;
// if you want only restaurantID
public SingleDetailsAboutPrice(String restaurantID)
{
InitializeComponent();
this.restaurantID = restaurantID;
}
}
以上是关于ListView ItemSelected打开详细信息页面MVVM的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin 表单 ListView ItemTapped/ItemSelected 命令绑定在 XAML
Xamarin表单ListView ItemTapped / ItemSelected在XAML上绑定命令