Warm tip: This article is reproduced from serverfault.com, please click

xaml-Xamarin

(xaml - Xamarin)

发布于 2020-12-01 13:58:01

尝试在带有项源的堆栈布局内触发命令。我不知道为什么NavigateToProductListViewShopTappedCommand没有被解雇。

尝试了多种命令方法:

1)

Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"
Command="{Binding Path=BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"

没有一个不起作用

代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:BoerPlaza.Controls.Shop"
             xmlns:local="clr-namespace:BoerPlaza.ViewModels"
             xmlns:behaviors="clr-namespace:BoerPlaza.Behaviors"
             x:Class="BoerPlaza.Views.Shop.MyShopsPage"
             x:Name="Page"
             Title="Mijn winkels">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout Margin="{StaticResource margin-side-std}"
                         Padding="{StaticResource padding-top-bottom-std}"
                         BindableLayout.ItemsSource="{Binding Shops}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <controls:ShopCardTemplateView Shop="{Binding .}"
                                                       ControlTemplate="{StaticResource ShopCardTemplateView}">
                            <controls:ShopCardTemplateView.GestureRecognizers>
                                <TapGestureRecognizer NumberOfTapsRequired="1"
                                                      Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyShopsListViewModel}}, Path=NavigateToProductListViewShopTappedCommand}"
                                                      CommandParameter="{Binding .}">
                                                      <!--Command="{Binding BindingContext.NavigateToProductListViewShopTappedCommand, Source={x:Reference Page}}"-->
                                </TapGestureRecognizer>
                            </controls:ShopCardTemplateView.GestureRecognizers>
                        </controls:ShopCardTemplateView>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

后面的代码

public partial class MyShopsPage : ContentPage
    {
        private readonly MyShopsListViewModel _viewModel;

        public MyShopsPage()
        {
            InitializeComponent();
            BindingContext = _viewModel = new MyShopsListViewModel(App.ShopDataStore, App.DialogService);
            _viewModel.LoadShopsOnUserIdCommand.Execute("B22698B8-42A2-4115-9631-1C2D1E2AC5F7");
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            _viewModel.OnAppearing();
        }
    }

ViewModel:

[QueryProperty(nameof(UserId), nameof(UserId))]
public class MyShopsListViewModel : BaseViewModel
{
    private string _userId;
    private ObservableCollection<ShopDbViewModel> _shops;
    private readonly IShopDataStore _shopDataStore;
    private readonly IDialogService _dialogService;

    public ObservableCollection<ShopDbViewModel> Shops
    {
        get
        {
            return _shops;
        }
        set
        {
            _shops = value;
            OnPropertyChanged(nameof(Shops));
        }
    }

    public void OnAppearing()
    {
        IsBusy = true;
    }
    public ICommand LoadShopsOnUserIdCommand { get; set; }
    public ICommand NavigateToProductListViewShopTappedCommand { get; set; }

    public MyShopsListViewModel(IShopDataStore shopDataStore, IDialogService dialogService)
    {
        this._shopDataStore = shopDataStore;
        this._dialogService = dialogService;

        Shops = new ObservableCollection<ShopDbViewModel>();

        LoadShopsOnUserIdCommand = new Command<string>(async (string userId) => await ExecuteLoadShopsOnUserId(userId));
        NavigateToProductListViewShopTappedCommand = new Command<ShopDbViewModel>(async (ShopDbViewModel shop) => await ExecuteNavigateToProductListViewShopTappedCommandAsync(shop));

    }

    private async Task ExecuteNavigateToProductListViewShopTappedCommandAsync(ShopDbViewModel shop)
    {
        if (shop == null)
            return;

        await Shell.Current.GoToAsync($"{nameof(ProductsPage)}?{nameof(MyProductsListViewModel.ShopId)}={shop.Id}");
    }

    public string UserId
    {
        get
        {
            return _userId;
        }
        set
        {
            _userId = value;
            LoadShopsOnUserIdCommand.Execute(value);
        }
    }

    private async Task ExecuteLoadShopsOnUserId(string userId)
    {
        var current = Connectivity.NetworkAccess;

        if (current == NetworkAccess.Internet)
        {
            try
            {
                Shops.Clear();
                var shops = await _shopDataStore.GetShopOnUserIdAsync(userId);
                foreach(var shop in shops)
                {
                    Shops.Add(shop);
                }
            }
            catch (Exception ex)
            {
                await _dialogService.ShowDialog(ex.Message, "An error has occurred", "OK");
            }
            finally
            {
                IsBusy = false;
            }
        }
        else
        {
            await _dialogService.ShowDialog("No active internet connection", "Connection error", "OK");
            IsBusy = false;
        }
       
    }
}
Questioner
QuanDar
Viewed
0
QuanDar 2020-12-02 14:53:38

我发现了问题

    <?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
             xmlns:customcontrols="clr-namespace:BoerPlaza.Controls"
             x:Class="BoerPlaza.Controls.Shop.ShopCardTemplateView">
    <ContentView.Resources>
        <ControlTemplate x:Key="ShopCardTemplateView">
            <!-- Card Header -->
            <!-- for displaying products and categories on homepage -->
            <StackLayout Spacing="1"
                         HorizontalOptions="FillAndExpand"
                         Margin="{StaticResource margin-card}">
                <!-- On click - shows the product detail view page -->
                <StackLayout.GestureRecognizers>
                    <TapGestureRecognizer NumberOfTapsRequired="1" />
                </StackLayout.GestureRecognizers>
                <!-- Image frame -->
                <Frame  BackgroundColor="{StaticResource image-box-color}"
                        CornerRadius="0"
                        HasShadow="False"
                        HorizontalOptions="FillAndExpand"
                        VerticalOptions="FillAndExpand"
                        HeightRequest="100">
                    <!-- Product Image -->

....

如你所见,这是我用于MyShopsPage的控件模板。这是一张购物卡。在这张购物卡中,我已经有一个StackLayout.GestureRecognizers。当我以某种方式单击控件模板时,实际上是在单击此模板。

我一直以为事件中的一切都是从上到下流动的,但这似乎有所不同。在xaml中,其他东西之上的东西并不意味着任何东西。