使用绑定从 CollectionView 的 ItemTemplate 调用时不会触发命令
Command is not triggered when called from CollectionView's ItemTemplate using Binding
我在使用绑定从 ViewModel 导航时遇到问题,命令异步方法 OnMovieClicked 根本不会触发。
public class MainViewModel : BaseViewModel
{
private List<Movie> popularMovies;
public List<Movie> PopularMovies
{
get => popularMovies;
set => SetProperty(ref popularMovies, value);
}
public ICommand NavigateToMovieCommand { get; set; }
private readonly TMDBService tmdbService;
private readonly INavigationService navigationService;
public MainViewModel()
{
tmdbService = new TMDBService();
navigationService = new NavigationService();
NavigateToMovieCommand = new Command<int>(async (id) => await OnMovieClicked(id));
InitAsync();
}
private async void InitAsync()
{
PopularMovies = await tmdbService.GetPopularMovies();
}
private async Task OnMovieClicked(int id)
{
Console.WriteLine("****Navigate");
var viewModel = new MovieViewModel(id);
await navigationService.PushAsync(new MoviePage(viewModel));
}
它没有向控制台写入任何内容,我已经测试了我的导航服务并且它工作正常
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MovieApp.ViewModels"
Title="New Releases"
x:Class="MovieApp.MainPage"
x:Name="MoviePage"
BackgroundColor="DarkSlateGray">
<ContentPage.BindingContext>
<viewmodels:MainViewModel/>
</ContentPage.BindingContext>
<CollectionView ItemsSource="{Binding PopularMovies}"
SelectionMode="None"
ItemSizingStrategy="MeasureAllItems"
ItemsLayout="VerticalGrid, 3">
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView>
<Frame HasShadow="True"
Margin="10"
WidthRequest="80"
BackgroundColor="LightSlateGray"
Padding="0"
CornerRadius="15">
<Grid RowDefinitions="120,25">
<Image Aspect="AspectFill"
Source="{Binding PosterPath}"
Grid.RowSpan="2"/>
<BoxView WidthRequest="80"
Grid.Row="1"
Opacity="0.85"
BackgroundColor="LightSlateGray"/>
<Label Grid.Row="1"
TextColor="White"
HorizontalOptions="CenterAndExpand"
Padding="8,0"
Text="{Binding Title}"
LineBreakMode="TailTruncation"/>
<Button Grid.RowSpan="2"
BackgroundColor="Blue"
Command="{Binding BindingContext.NavigateToMovieCommand, Source={x:Reference MoviePage}}"
CommandParameter="{Binding Id}"/>
</Grid>
</Frame>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
我已经将 x:Name 和 x:Reference 属性添加到页面和命令
我不认为我在 XAML 文件中做错了什么,但这一定是一个有约束力的问题,因为它不会将日志行打印到控制台。
更新:
这是电影模型
public partial class Movie
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("poster_path")]
public string PosterPath {
get;
set;
}
[JsonProperty("release_date")]
public string ReleaseDate { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("vote_average")]
public double VoteAverage { get; set; }
[JsonProperty("credits", NullValueHandling = NullValueHandling.Ignore)]
public Credits Credits { get; set; }
}
你的代码没问题,没有问题,但是你没有post一些关于Movie
的代码,Id property
类型是int
或string
,如果 Movie
class Id property
是 string
,传递 Id
参数作为 int
输入 NavigateToMovieCommand
,命令不会开火。
NavigateToMovieCommand = new Command<int>(async (id) => await OnMovieClicked(id));
我用下面的Movie
class,设置Id
属性类型为int
,用你的代码测试,Buttom命令可以解雇了,没问题。
public class Movie
{
public int Id { get; set; }
public string PosterPath { get; set; }
public string Title { get; set; }
}
我在使用绑定从 ViewModel 导航时遇到问题,命令异步方法 OnMovieClicked 根本不会触发。
public class MainViewModel : BaseViewModel
{
private List<Movie> popularMovies;
public List<Movie> PopularMovies
{
get => popularMovies;
set => SetProperty(ref popularMovies, value);
}
public ICommand NavigateToMovieCommand { get; set; }
private readonly TMDBService tmdbService;
private readonly INavigationService navigationService;
public MainViewModel()
{
tmdbService = new TMDBService();
navigationService = new NavigationService();
NavigateToMovieCommand = new Command<int>(async (id) => await OnMovieClicked(id));
InitAsync();
}
private async void InitAsync()
{
PopularMovies = await tmdbService.GetPopularMovies();
}
private async Task OnMovieClicked(int id)
{
Console.WriteLine("****Navigate");
var viewModel = new MovieViewModel(id);
await navigationService.PushAsync(new MoviePage(viewModel));
}
它没有向控制台写入任何内容,我已经测试了我的导航服务并且它工作正常
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MovieApp.ViewModels"
Title="New Releases"
x:Class="MovieApp.MainPage"
x:Name="MoviePage"
BackgroundColor="DarkSlateGray">
<ContentPage.BindingContext>
<viewmodels:MainViewModel/>
</ContentPage.BindingContext>
<CollectionView ItemsSource="{Binding PopularMovies}"
SelectionMode="None"
ItemSizingStrategy="MeasureAllItems"
ItemsLayout="VerticalGrid, 3">
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView>
<Frame HasShadow="True"
Margin="10"
WidthRequest="80"
BackgroundColor="LightSlateGray"
Padding="0"
CornerRadius="15">
<Grid RowDefinitions="120,25">
<Image Aspect="AspectFill"
Source="{Binding PosterPath}"
Grid.RowSpan="2"/>
<BoxView WidthRequest="80"
Grid.Row="1"
Opacity="0.85"
BackgroundColor="LightSlateGray"/>
<Label Grid.Row="1"
TextColor="White"
HorizontalOptions="CenterAndExpand"
Padding="8,0"
Text="{Binding Title}"
LineBreakMode="TailTruncation"/>
<Button Grid.RowSpan="2"
BackgroundColor="Blue"
Command="{Binding BindingContext.NavigateToMovieCommand, Source={x:Reference MoviePage}}"
CommandParameter="{Binding Id}"/>
</Grid>
</Frame>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
我已经将 x:Name 和 x:Reference 属性添加到页面和命令
我不认为我在 XAML 文件中做错了什么,但这一定是一个有约束力的问题,因为它不会将日志行打印到控制台。
更新:
这是电影模型
public partial class Movie
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("poster_path")]
public string PosterPath {
get;
set;
}
[JsonProperty("release_date")]
public string ReleaseDate { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("vote_average")]
public double VoteAverage { get; set; }
[JsonProperty("credits", NullValueHandling = NullValueHandling.Ignore)]
public Credits Credits { get; set; }
}
你的代码没问题,没有问题,但是你没有post一些关于Movie
的代码,Id property
类型是int
或string
,如果 Movie
class Id property
是 string
,传递 Id
参数作为 int
输入 NavigateToMovieCommand
,命令不会开火。
NavigateToMovieCommand = new Command<int>(async (id) => await OnMovieClicked(id));
我用下面的Movie
class,设置Id
属性类型为int
,用你的代码测试,Buttom命令可以解雇了,没问题。
public class Movie
{
public int Id { get; set; }
public string PosterPath { get; set; }
public string Title { get; set; }
}