[英]Trouble with showing a Mahapps.Metro Dialog with a ReactiveUi Command
我正在嘗試在我的項目中使用 Mahapps 對話框,但是當從我的 ViewModel 中的 ReactivUI 命令觸發時無法讓它們工作。在視圖的 XAML 中,我已經注冊了對話框。
xmlns:dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
dialogs:DialogParticipation.Register="{Binding}"
我還有一個綁定到 ShowDialog 命令的按鈕。
this.BindCommand(viewModel, vm => vm.ShowDialog, x => x.button);
最后,在我的 ViewModel 中,我設置了 RxUI 命令和 dialogcoordinator 實例。
public MainWindowViewModel(IDialogCoordinator dialogCoordinator)
{
_dialogCoordinator = dialogCoordinator;
ShowDialog = ReactiveCommand.CreateFromTask(async () =>
{
await _dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!");
});
ShowDialog.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex.ToString()));
}
無論我嘗試過什么,它總是拋出相同的錯誤
System.InvalidOperationException: Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext.
我不確定是否還需要其他任何東西才能使對話框正常工作,或者我是否只是錯誤地使用了 RxUI 中的命令
我在另一個 MVVM 框架(MVVM Light Toolkit)上遇到了同樣的問題。 但是框架似乎不是問題。 這是時間問題。 DialogCoordinator 不能從構造函數訪問。 我個人將所有代碼從構造函數移動到正在被觸發的 RelayCommand
<controls:MetroWindow
x:Class="UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
dialog:DialogParticipation.Register="{Binding}"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
d:DataContext="{d:DesignInstance vm:MainViewModel}"
mc:Ignorable="d">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContentRendered">
<i:InvokeCommandAction Command="{Binding StartupCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
我嘗試了不同的事件,例如 Loaded,它在某些情況下有效,但“ContentRendered”始終在 VM 中有效,我有以下代碼:
public ICommand StartupCommand
{
get
{
return new RelayCommand(async ()=>
{
this.AccountName = await
dialogCoordinator.ShowInputAsync(this, "Welcome", "Please insert your account name");
});
}
}
所以基本上它似乎還沒有直接注冊,但在加載內容后它是。 (在這個例子中,我使用了 ShowInputAsync 但它應該與 ShowMessageAsync 一樣工作)
這似乎是一個時間問題 - 當我第一次開始玩這個時,我通過從 View 的 Loaded 事件而不是它的構造函數設置 VM 的 DialogCoordinator 實例來讓它工作。
我已經在https://github.com/dwarry/ReactiveUiMahAppsDialog 上組合了一個最小的工作應用程序來演示這一點。 它使用 ReactiveUi 的正常交互機制來觸發顯示對話框。 與此保持一致,我已將其放在視圖中,但我不明白為什么如果您願意,它不能適應從 ViewModel 執行此操作。 要注意的另一件事是,您需要在離開交互處理程序之前等待對話框關閉,否則 ReactiveUI 將拋出 UnhandledInteractionException。
對我來說,使用ContentRendered
事件沒有做任何事情; 我仍然收到異常InvalidOperationException: Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext
InvalidOperationException: Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext
。
我的解決方案基於 Kent Boogaart 的書籍樣本。
看法:
using System.Reactive;
using System.Reactive.Disposables;
using System.Windows;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using ReactiveUI;
using Splat;
namespace ReactiveUIMahAppsDialog
{
public partial class ChildView
{
public ChildView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
ViewModel ??= Locator.Current.GetService<ChildViewModel>() ?? new ChildViewModel();
this.BindCommand(ViewModel,
viewModel => viewModel.LogInUser,
view => view.Test)
.DisposeWith(disposables);
this.ViewModel.Message
.RegisterHandler(async interaction =>
{
MetroWindow window = (MetroWindow) Window.GetWindow(this);
await window.ShowMessageAsync("test", "test");
interaction.SetOutput(Unit.Default);
})
.DisposeWith(disposables);
});
}
}
}
<reactiveUi:ReactiveUserControl
x:Class="ReactiveUIMahAppsDialog.ChildView"
x:TypeArguments="viewModels:ChildViewModel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:reactiveUi="http://reactiveui.net"
xmlns:viewModels="clr-namespace:ReactiveUIMahAppsDialog"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button x:Name="Test" Content="Show Dialog" Width="100" Height="100"/>
</Grid>
</reactiveUi:ReactiveUserControl>
在MetroWindow
托管反應式用戶控件。
視圖模型:
using System.Reactive;
using System.Reactive.Linq;
using ReactiveUI;
namespace ReactiveUIMahAppsDialog
{
public class ChildViewModel : ReactiveObject
{
public ChildViewModel()
{
Message = new Interaction<Unit, Unit>();
LogInUser = ReactiveCommand.CreateFromTask(async _ => await Message.Handle(Unit.Default));
}
public ReactiveCommand<Unit, Unit> LogInUser { get; }
public Interaction<Unit, Unit> Message { get; }
}
}
完整代碼可以在這里找到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.