页面出现时调用Xamarin表单弹出页面按钮命令

时间:2019-02-28 05:07:32

标签: xamarin.forms

我正在使用Rg.Plugins.Popup,并且我有一个弹出页面,其中包含一个按钮,我想用它来关闭弹出窗口。弹出窗口显示得很好,我现在可以通过选择背景将其关闭。但为了获得良好的用户体验,UX也想要一个按钮。该按钮的连接方式如下:

在我的XAML中:

<Button BackgroundColor="#2B653E"
                Margin="0,20,0,0"
                Padding="10,10,10,10"
                Command="{Binding OnBtnOkTapped}"
                Text="OK"
                TextColor="White"
                x:Name="btnOk"/>

在我的ViewModel中:

public ICommand OnBtnOkTapped = new Command(async () => { await PopupNavigation.Instance.PopAllAsync(); });

我已经确认绑定正常(其他属性正常)。但是当我点击按钮时什么也没发生。因此,我在此行上设置了一个断点,发现弹出窗口出现时它被称为

当我在弹出窗口中点击此按钮时,它不会被调用(即,我没有达到断点)。

有人可以告诉我为什么会这样吗?

编辑:做了一些进一步的测试,从Command更改为Clicked,然后处理背后的代码而不是ViewModel产生了预期的结果。只是不明白为什么页面加载时而不是单击按钮时调用ICommand。

编辑2:

按照@ G.hakim的要求,这是此页面的完整XAML:

<?xml version="1.0" encoding="UTF-8"?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
             xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
             xmlns:lottie="clr-namespace:Lottie.Forms;assembly=Lottie.Forms"
             x:Class="MyApp.PopUpPages.ReservationResult"
             BackgroundColor="Transparent">
    <pages:PopupPage.Animation>
        <animations:ScaleAnimation
            PositionIn="Center"
            PositionOut="Center"
            ScaleIn="1.2"
            ScaleOut="0.8"
            DurationIn="400"
            DurationOut="300"
            EasingIn="SinIn"
            EasingOut="SinOut"
            HasBackgroundAnimation="false"/>
    </pages:PopupPage.Animation>
    <StackLayout
        HorizontalOptions="Center"
        VerticalOptions="Center"
        WidthRequest="300"
        HeightRequest="400"
        BackgroundColor="White"
        Padding="30">
        <lottie:AnimationView x:Name="ResultAnimation"
             Animation="{Binding AnimationRef}"
             AutoPlay="true"
             Loop="false"
             VerticalOptions="Center"
             HorizontalOptions="Center"
             HeightRequest="200"
             WidthRequest="200"
             Scale="1"/>
        <Label Text="{Binding ResponseTitle}"
           Margin="0,20,0,0"
           HorizontalOptions="Center"
           VerticalOptions="Start"
           TextColor="#2B653E"
           FontAttributes="Bold"
           FontSize="Large"/>

        <Label Text="{Binding ResponseMessage}"
           HorizontalOptions="Center"
           VerticalOptions="End"
           TextColor="#2B653E"/>

        <Button BackgroundColor="#2B653E"
                Margin="0,20,0,0"
                Padding="10,10,10,10"
                Clicked="Handle_Clicked"
                Text="OK"
                TextColor="White"
                x:Name="btnOk"/>       
    </StackLayout>
</pages:PopupPage>

这是ViewModel:

using System;
using System.Windows.Input;
using Rg.Plugins.Popup.Services;
using MyApp.Models;
using Xamarin.Forms;

namespace MyApp.ViewModels
{
    public class ReservationResultViewModel : ViewModel
    {
        public string ResponseTitle { get; set; }
        public string ResponseMessage { get; set; }
        public string AnimationRef { get; set; }

        public ICommand OnBtnOkTapped = new Command(async () => { await PopupNavigation.Instance.PopAllAsync(); });

        public ReservationResultViewModel(ReservationStatus status)
        {
            switch (status.status)
            {
                case ReservationStatus.Status.Booked:
                    //
                    ResponseTitle = "Booked!";
                    ResponseMessage = "We've received your reservation, see you then!";
                    AnimationRef = "1166-tick.json";
                    break;
                case ReservationStatus.Status.Full:
                    //
                    ResponseTitle = "Well this is embarrassing...";
                    ResponseMessage = "Looks like this is a really popular time and we're full. Head over to the Contact page though, we still might be able to help!";
                    AnimationRef = "4284-notification.json";
                    break;
                case ReservationStatus.Status.HttpError:
                    //
                    ResponseTitle = "Hmmm...";
                    ResponseMessage = "Something went wrong, but we're pretty sure its our fault. Can you check your form and try again?";
                    AnimationRef = "3932-error-cross.json";
                    break;
                case ReservationStatus.Status.ServerUnavailable:
                    //
                    ResponseTitle = "It's not you, it's me...";
                    ResponseMessage = "So sorry, it looks like the reservation service is down! Please head over to the Contact page, or try again later.";
                    AnimationRef = "4386-connection-error.json";
                    break;
            }

        }
    }
}

该视图后面的代码:

using System;
using System.Collections.Generic;
using Rg.Plugins.Popup.Pages;
using Rg.Plugins.Popup.Services;
using MyAPp.Models;
using MyApp.ViewModels;
using Xamarin.Forms;

namespace MyApp.PopUpPages
{
    public partial class ReservationResult : PopupPage
    {
        public ReservationResultViewModel viewModel { get; set; }

        public ReservationResult(ReservationResultViewModel vm)
        {
            InitializeComponent();
            viewModel = vm;
            BindingContext = viewModel;
        }

        async void Handle_Clicked(object sender, System.EventArgs e)
        {
            await PopupNavigation.Instance.PopAllAsync();
            //throw new NotImplementedException();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

所有特定于UI的操作都需要在设备主线程(UI线程)上执行。

所以您的命令应如下所示:

public ICommand OnBtnOkTapped = new Command( Device.BeginInvokeOnMainThread(() => {PopupNavigation.Instance.PopAllAsync()} );

答案 1 :(得分:0)

好的,您将需要进行以下更改:

向按钮(XAML)添加命令,如下所示:

 Command="{Binding MoreButtonCommand}" 

向您的ViewModel类添加相同的属性,如下所示:

public ICommand MoreButtonCommand { get; set; }

在ViewModel的Constructor中初始化此属性:

MoreButtonCommand = new Command(MoreButtonPressed);

然后创建一个返回void的方法作为命令的参数传递:

 private async void MoreButtonPressed(object obj)
    {
       await PopupNavigation.Instance.PopAllAsync();
    }

如果您不想随意还原,这应该对您有用

祝你好运

编辑:

原因(因为这不起作用)是因为您使用的是字段,现在FIELD不再是您使用BindingProperty连接的内容。绑定属性仅接受属性{ {1}}作为输入,因此您以前无法对其进行接线,但现在可以使用