如何在 Xamarin 中从我的 ViewModel 创建警报弹出窗口?
How do I create an alert popup from my ViewModel in Xamarin?
我正在使用 MVVM 模式开发我的 Xamarin 应用程序。我想在用户按下按钮时向用户显示警报。
我用
声明我的 ViewModel
class MainPageViewModel : BindableBase {
遗憾的是,我无法直接从 ViewModel 中访问 Page
对象。我怎样才能最好地显示我的警报?
如果您使用普通的 MVVM 模式,您可以在视图模型中调用以下代码。
App.current.MainPage.DisplayAlert("","","");
要显示 Alert
在您的 ViewModel 中编写以下代码 class
public class MainViewModel
{
public ICommand ShowAlertCommand { get; set; }
public MainViewModel()
{
ShowAlertCommand = new Command(get => MakeAlter());
}
void MakeAlter()
{
Application.Current.MainPage.DisplayAlert("Alert", "Hello", "Cancel", "ok");
}
}
在 xaml
中将您的 Command
设置为 Button
<StackLayout>
<Button Text="Click for alert" Command="{Binding ShowAlertCommand}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
在 xaml 文件后面的代码中设置 BindingContext
。如果您 xaml 文件 MainPage.xaml
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
您可以使用 Prism 的 PageDialogService,它使您的 ViewModel 非常干净且可测试。
聚会迟到了,但正如 Nick Turner 在许多评论中提到的那样,目前给出的解决方案要求视图模型引用视图,该视图是 MVVM 的 antipattern/infringement。此外,您会在视图模型单元测试中遇到错误,例如:You MUST call Xamarin.Forms.Init();在使用它之前。
相反,您可以创建一个包含警报框代码的界面,然后按如下方式在视图模型中使用:
接口:
public interface IDialogService
{
Task ShowAlertAsync(string message, string title, string buttonLabel);
}
实施(使用 ACR.UserDialogs NuGet 包):
public class DialogService : IDialogService
{
public async Task ShowAlertAsync(string message, string title, string buttonLabel)
{
if (App.IsActive)
await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);
else
{
MessagingCenter.Instance.Subscribe<object>(this, MessageKeys.AppIsActive, async (obj) =>
{
await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);
MessagingCenter.Instance.Unsubscribe<object>(this, MessageKeys.AppIsActive);
});
}
}
}
视图模型:
public class TestViewModel
{
private readonly IDialogService _dialogService;
public TestViewModel(IDialogService dialogService)
{
//IoC handles _dialogService implementation
_dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
}
public ICommand TestCommand => new Command(async () => await TestAsync());
private async Task TestAsync()
{
await _dialogService.ShowAlertAsync("The message alert will show", "The title of the alert", "The label of the button");
}
}
然后可以将 TestCommand 绑定到 xaml:
中的按钮
<Button x:Name="testButton" Command="{Binding TestCommand}">
创建这样的弹出窗口是个好主意吗? (从我的 ViewModel 调用)
private void OpenPopUp()
{
Application.Current.MainPage.Navigation.ShowPopup(new CustomPopUp());
}
您可以在此处找到有关如何创建自定义小狗的指南:
https://www.youtube.com/watch?v=DkQbTarAE18
对我来说效果很好,但我对 Xamarin 还很陌生。
对于Shell应用程序,我能够像这样实现
await Shell.Current.DisplayAlert("Title", "Message", "Cancel");
我正在使用 MVVM 模式开发我的 Xamarin 应用程序。我想在用户按下按钮时向用户显示警报。
我用
声明我的 ViewModelclass MainPageViewModel : BindableBase {
遗憾的是,我无法直接从 ViewModel 中访问 Page
对象。我怎样才能最好地显示我的警报?
如果您使用普通的 MVVM 模式,您可以在视图模型中调用以下代码。
App.current.MainPage.DisplayAlert("","","");
要显示 Alert
在您的 ViewModel 中编写以下代码 class
public class MainViewModel
{
public ICommand ShowAlertCommand { get; set; }
public MainViewModel()
{
ShowAlertCommand = new Command(get => MakeAlter());
}
void MakeAlter()
{
Application.Current.MainPage.DisplayAlert("Alert", "Hello", "Cancel", "ok");
}
}
在 xaml
中将您的Command
设置为 Button
<StackLayout>
<Button Text="Click for alert" Command="{Binding ShowAlertCommand}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
在 xaml 文件后面的代码中设置 BindingContext
。如果您 xaml 文件 MainPage.xaml
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
您可以使用 Prism 的 PageDialogService,它使您的 ViewModel 非常干净且可测试。
聚会迟到了,但正如 Nick Turner 在许多评论中提到的那样,目前给出的解决方案要求视图模型引用视图,该视图是 MVVM 的 antipattern/infringement。此外,您会在视图模型单元测试中遇到错误,例如:You MUST call Xamarin.Forms.Init();在使用它之前。
相反,您可以创建一个包含警报框代码的界面,然后按如下方式在视图模型中使用:
接口:
public interface IDialogService
{
Task ShowAlertAsync(string message, string title, string buttonLabel);
}
实施(使用 ACR.UserDialogs NuGet 包):
public class DialogService : IDialogService
{
public async Task ShowAlertAsync(string message, string title, string buttonLabel)
{
if (App.IsActive)
await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);
else
{
MessagingCenter.Instance.Subscribe<object>(this, MessageKeys.AppIsActive, async (obj) =>
{
await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);
MessagingCenter.Instance.Unsubscribe<object>(this, MessageKeys.AppIsActive);
});
}
}
}
视图模型:
public class TestViewModel
{
private readonly IDialogService _dialogService;
public TestViewModel(IDialogService dialogService)
{
//IoC handles _dialogService implementation
_dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
}
public ICommand TestCommand => new Command(async () => await TestAsync());
private async Task TestAsync()
{
await _dialogService.ShowAlertAsync("The message alert will show", "The title of the alert", "The label of the button");
}
}
然后可以将 TestCommand 绑定到 xaml:
中的按钮<Button x:Name="testButton" Command="{Binding TestCommand}">
创建这样的弹出窗口是个好主意吗? (从我的 ViewModel 调用)
private void OpenPopUp()
{
Application.Current.MainPage.Navigation.ShowPopup(new CustomPopUp());
}
您可以在此处找到有关如何创建自定义小狗的指南: https://www.youtube.com/watch?v=DkQbTarAE18
对我来说效果很好,但我对 Xamarin 还很陌生。
对于Shell应用程序,我能够像这样实现
await Shell.Current.DisplayAlert("Title", "Message", "Cancel");