[英]Xamarin.Forms and Prism - How to pass data and navigate to another view?
This's my first question here, so hi everybody.这是我在这里的第一个问题,大家好。 I'm working on the mobile app in Xamarin.Forms with Prism.我正在使用 Prism 开发 Xamarin.Forms 中的移动应用程序。 I've created ListView where shown data from the database.我创建了 ListView,其中显示了数据库中的数据。
When the user clicks in the selected row app should navigate to a new view and pass the selected item from ListView.当用户在所选行中单击时,应用程序应导航到新视图并从 ListView 传递所选项目。
<ListView x:Name="DefectsBase"
RowHeight="65"
ItemsSource="{Binding Defects}"
ItemSelected="ShowDetailsEvent"
IsPullToRefreshEnabled="true"
RefreshCommand="{Binding Refresh}"
IsRefreshing="{Binding IsRefreshing}">
Code backend:代码后端:
async void ShowDetailsEvent(object sender, EventArgs e)
{
var myListView = (ListView)sender;
var myItem = myListView.SelectedItem;
var p = new NavigationParameters();
p.Add("selectedDefect", myItem);
await _navigationService.NavigateAsync("DefectDetailsView", p);
}
Unfortunately, the app doesn't respond to pressing the selected row in ListView.不幸的是,应用程序没有响应在 ListView 中按下选定的行。
As I can see you are already using Prism
and you have a List page with Items and you want to navigate to some details page based on the selected/taped/chosen item which the user taps in the ListView.正如我所看到的,您已经在使用Prism
,并且您有一个包含项目的列表页面,并且您希望根据用户在 ListView 中点击的选定/录制/选择的项目导航到一些详细信息页面。
The idea is to move as much code and logic as we can to the view model and keep our code-behind.我们的想法是将尽可能多的代码和逻辑移动到视图 model 并保留我们的代码隐藏。 This is pretty easy to solve using Prism
and EventToCommand
behaviour.使用Prism
和EventToCommand
行为很容易解决这个问题。
In the example and answer below, I will show you how to solve this with few lines of code, with a nice code approach.在下面的示例和答案中,我将向您展示如何用几行代码和一种很好的代码方法来解决这个问题。
First of all, I recommend you use EventToCommand
behaviour, you can include it with prism xmlns, like this: xmlns:prism="http://prismlibrary.com"
, later on, you can use it with ListView.首先,我建议您使用EventToCommand
行为,您可以将其包含在 prism xmlns 中,如下所示: xmlns:prism="http://prismlibrary.com"
,稍后您可以将其与 ListView 一起使用。
Remove ItemSelected event from your ListView and move the markup about it to the <ListView.Behaviors>
part.从 ListView 中删除 ItemSelected 事件并将有关它的标记移动到<ListView.Behaviors>
部分。 Here is my code sample for the ListView
which binds to some ObserverableCollection
of the Car models:这是我绑定到汽车模型的一些ObserverableCollection
的ListView
的代码示例:
<ListView ItemsSource="{Binding Cars}">
<ListView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<prism:EventToCommandBehavior EventName="ItemTapped"
Command="{Binding SelectedCarCommand}"
EventArgsParameterPath="Item" />
</ListView.Behaviors>
The main part here is <ListView.Behaviors>
, where you can see that I am binding to the SelectedCarCommand which will be invoked when the user taps on some of the items from the list.这里的主要部分是<ListView.Behaviors>
,您可以在其中看到我绑定到 SelectedCarCommand ,当用户点击列表中的某些项目时将调用该命令。 I am using the ItemTapped
event for this and passing the current "taped" item from the list as a parameter.我为此使用ItemTapped
事件,并将列表中当前的“录音”项目作为参数传递。
In order to follow this XAML part in my view model of this page, I have declared the DelegateCommand
and method which will be called when the command is invoked.为了在此页面的 model 中遵循此 XAML 部分,我声明了DelegateCommand
和调用命令时将调用的方法。 The view model part looks like this:视图 model 部分如下所示:
This is my CarListPageViewModel, take a look at DelegateCommand and SelectedCar method.这是我的 CarListPageViewModel,看看 DelegateCommand 和 SelectedCar 方法。
public class CarListPageViewModel
{
private readonly INavigationService _navigationService;
public ObservableCollection<Car> Cars { get; set; }
public DelegateCommand<Car> SelectedCarCommand { get; private set; }
public CarListPageViewModel(INavigationService navigationService, IDataProvider dataProvider)
{
_navigationService = navigationService;
// Insert test data into collection of Cars
Cars = new ObservableCollection<Car>(dataProvider.GetData());
SelectedCarCommand = new DelegateCommand<Car>(SelectedCar);
}
private async void SelectedCar(Car selectedCar)
{
NavigationParameters navigationParameters = new NavigationParameters
{
{ "selectedCar", selectedCar }
};
await _navigationService.NavigateAsync(nameof(CarDetailsPage), navigationParameters);
}
}
As you can see we have DelegateCommand
defined with the type of parameter which will be passed, in my case, this is the Car class, the same class as our items in the ListView.正如你所看到的,我们定义了DelegateCommand
,参数的类型将被传递,在我的例子中,这是 Car class,与 ListView 中的项目相同的 class。
In the constructor, I did my initialization and defined the method which will be called, that method has a parameter of the type Car.在构造函数中,我进行了初始化并定义了将要调用的方法,该方法有一个 Car 类型的参数。
When the user taps on one of the items in the ListView, SelectedCar (method) will be called and we can pass the data to the next view using NavigationParameters
and NavigationService
.当用户点击 ListView 中的一个项目时,将调用 SelectedCar(方法),我们可以使用NavigationParameters
和NavigationService
将数据传递给下一个视图。
In order to retrieve the passed data we can use INavigationAware
in the details view model and with the OnNavigatedTo
method, access the data which is being passed.为了检索传递的数据,我们可以在详细视图 model 中使用INavigationAware
并使用OnNavigatedTo
方法访问正在传递的数据。
This is my CarDetailsPageViewModel, take a look at OnNavigatedTo
method.这是我的 CarDetailsPageViewModel,看看OnNavigatedTo
方法。
public class CarDetailsPageViewModel : BindableBase, INavigationAware
{
private string carTitle;
public string CarTitle
{
get { return carTitle; }
set { SetProperty(ref carTitle, value); }
}
private string photoUrl;
public string PhotoUrl
{
get { return photoUrl; }
set { SetProperty(ref photoUrl, value); }
}
public CarDetailsPageViewModel() { }
public void OnNavigatedTo(INavigationParameters parameters)
{
if (parameters.ContainsKey("selectedCar"))
{
Car car = parameters.GetValue<Car>("selectedCar");
if (car != null)
{
CarTitle = $"{car.Make} {car.Model}";
PhotoUrl = car.PhotoUrl;
}
}
}
public void OnNavigatedFrom(INavigationParameters parameters) { }
}
From this answer and example, you can see:从这个答案和示例中,您可以看到:
EventToCommand
behaviour with ListView
如何将EventToCommand
行为与ListView
一起使用DelegateCommand
with passing parameter定义和使用带传递参数的DelegateCommand
Code and this sample you can find on my GitHub profile here .您可以在我的 GitHub 配置文件中找到代码和此示例。
Hope this answer was helpful for you!希望这个答案对你有帮助!
Wishing you lots of luck with coding!祝你编码好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.