问题描述
这是我在这里的第一个问题,大家好。我在Xamarin开发移动应用程序。Forms with Prism我已创建了ListView,其中显示了数据库中的数据。
当用户在所选行中单击时,应用程序应导航到新视图并传递来自ListView的所选项目。
<ListView x:Name="DefectsBase"
RowHeight="65"
ItemsSource="{Binding Defects}"
ItemSelected="ShowDetailsEvent"
IsPullToRefreshEnabled="true"
RefreshCommand="{Binding Refresh}"
IsRefreshing="{Binding IsRefreshing}">
代码后端:
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);
}
遗憾的是,该应用程序没有响应按下ListView中的选定行。
推荐答案
我可以看到您已经在使用Prism
,并且您有一个包含项目的列表页面,并且您希望根据用户在列表视图中点击的所选/已录制/所选项目导航到某些详细信息页面。
我们的想法是将尽可能多的代码和逻辑移到视图模型中,并保持代码隐藏。使用Prism
和EventToCommand
行为很容易解决此问题。
在下面的示例和答案中,我将向您展示如何用几行代码和一种很好的代码方法解决这个问题。
首先,我建议您使用EventToCommand
行为,您可以将其包含在棱镜xmlns中,如下所示:xmlns:prism="http://prismlibrary.com"
,稍后您可以将其用于ListView。
<ListView.Behaviors>
部分。以下是我的ListView
代码示例,它绑定到一些ObserverableCollection
汽车模型:<ListView ItemsSource="{Binding Cars}">
<ListView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<prism:EventToCommandBehavior EventName="ItemTapped"
Command="{Binding SelectedCarCommand}"
EventArgsParameterPath="Item" />
</ListView.Behaviors>
这里的主要部分是<ListView.Behaviors>
,您可以看到我正在绑定到SelectedCarCommand,该命令将在用户点击列表中的一些项时被调用。为此,我使用ItemTapped
事件,并将列表中当前的&Quot;Tapted&Quot;项作为参数传递。
为了在我的页面视图模型中遵循这个XAML部件,我声明了DelegateCommand
和方法,当调用该命令时将调用该方法。视图模型部件如下所示:
这是我的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);
}
}
如您所见,我们定义了DelegateCommand
要传递的参数类型,在我的例子中,这是Car类,与ListView中的项相同。
在构造函数中,我进行了初始化并定义了将被调用的方法,该方法有一个Car类型的参数。
当用户点击ListView中的一项时,将调用SelectedCar(方法),我们可以使用NavigationParameters
和NavigationService
将数据传递到下一个视图。
为了检索传递的数据,我们可以在详细信息视图模型中使用INavigationAware
,并使用OnNavigatedTo
方法访问正在传递的数据。
这是我的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) { }
}
从这个答案和示例中,您可以看到:
- 如何,使用
EventToCommand
行为ListView
- 定义并使用
DelegateCommand
和传递参数 - 如何导航到另一个视图并传递导航参数和
- .最后如何访问传递的数据。
代码和此示例,您可以在我的GitHub个人资料中找到here。
希望此答案对您有帮助!
祝您编码好运!👋
这篇关于Xamarin.Forms和Prism-如何传递数据并导航到另一个视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!