我正在使用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();
}
}
}
答案 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}}作为输入,因此您以前无法对其进行接线,但现在可以使用