C# 返回到UWP XAML页面ContentDialog后。RunAsync()导致';值不在预期范围内;
使用UWP和MVVM Light,我有一个程序可以多次使用相同的页面和视图模型来处理不同的数据。每个页面/视图模型对都分配了一个匹配的ID,以便它们可以更容易地相互引用。页面上有一个显示ContentDialog的按钮 第一次打开其中一个页面时,ContentDialog会正常打开,但如果页面被保留然后返回,则为ContentDialog调用ShowAsync会导致非常描述性的ArgumentException:“值不在预期范围内。” 视图模型C# 返回到UWP XAML页面ContentDialog后。RunAsync()导致';值不在预期范围内;,c#,xaml,uwp,mvvm-light,C#,Xaml,Uwp,Mvvm Light,使用UWP和MVVM Light,我有一个程序可以多次使用相同的页面和视图模型来处理不同的数据。每个页面/视图模型对都分配了一个匹配的ID,以便它们可以更容易地相互引用。页面上有一个显示ContentDialog的按钮 第一次打开其中一个页面时,ContentDialog会正常打开,但如果页面被保留然后返回,则为ContentDialog调用ShowAsync会导致非常描述性的ArgumentException:“值不在预期范围内。” 视图模型 public RelayCommand LockB
public RelayCommand LockButtonCommand => new RelayCommand(() => lockButtonClicked());
private void lockButtonClicked()
{
System.Diagnostics.Debug.WriteLine("Button clicked on VM " + myID);
Messenger.Default.Send(new ShowPassphraseDialogMessage(), myID);
}
页面代码隐藏
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!idsRegistered.Contains(myID))
{
Messenger.Default.Register<ShowPassphraseDialogMessage>(this, myID, showDiag);
System.Diagnostics.Debug.WriteLine("Registered messages for " + myID);
idsRegistered.Add(myID);
}
}
private async void showDiag(object msg)
{
System.Diagnostics.Debug.WriteLine("Showing dialog for " + myID);
if (activePageID != myID)
return;
await PassphraseDialog.ShowAsync();
}
受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
如果(!idspnRegistered.Contains(myID))
{
Messenger.Default.Register(this、myID、showDiag);
System.Diagnostics.Debug.WriteLine(“为“+myID”注册的消息);
idsRegistered.Add(myID);
}
}
私有异步void showDiag(对象消息)
{
System.Diagnostics.Debug.WriteLine(“显示“+myID”的对话框);
如果(activePageID!=myID)
返回;
等待PassphraseDialog.ShowAsync();
}
ContentDialog XAML
<ContentDialog x:Name="PassphraseDialog"
x:Uid="Page_PassDialog"
PrimaryButtonText="Enter"
SecondaryButtonText="Cancel"
PrimaryButtonCommand="{x:Bind ViewModel.PassDialogEnterCommand}"
Closing="PassphraseDialog_Closing">
<StackPanel>
<TextBlock x:Uid="Page_PassDialogText" />
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<PasswordBox x:Name="PassphraseDialogInput"
Password="{x:Bind ViewModel.PassDialogInputText, Mode=TwoWay}"
helper:EnterKeyHelpers.EnterKeyCommand="{x:Bind ViewModel.PassDialogEnterCommand}" />
<ProgressRing Margin="8,0,0,12"
IsActive="{x:Bind ViewModel.PassDialogLoading, Mode=OneWay}" />
</StackPanel>
<TextBlock Text="{x:Bind ViewModel.PassDialogErrorText, Mode=OneWay}"
Foreground="{ThemeResource SystemErrorTextColor}"/>
</StackPanel>
</ContentDialog>
我首先担心的是,在我的设置中,showDiag方法被多次调用。因此,我做了几项测试来了解以下内容:
我不确定这是否相关,但我发现通过此设置,每次导航到该页面时都会调用页面构造函数。当您需要多次使用同一页面时,请缓存该页面 试试这个:
private bool\u isInit=false;
公共MyPage()
{
this.InitializeComponent();
NavigationCacheMode=NavigationCacheMode.Enabled;
}
受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
如果(e.NavigationMode==NavigationMode.Back | | | | isInit)
返回;
//做点什么。。。
_isInit=true;
}
缓存页面时,它会保持页面的当前状态,这意味着两件事:
ContentDialog
不会被新创建页面的ContentDialog
替换,从而导致错误致以最良好的祝愿。谢谢Richard。这在很大程度上解决了我的问题,但是使用MVVM Light,我有多个ViewModel实例,这些实例在缓存后不会反映在视图中。您知道我是否有办法通知视图我已重新分配ViewModel?看起来重新分配VIEW模型属性本身不会更新任何绑定。您可以考虑不将VIEW模型创建为变量,而是A,这样当您更改它时,您将通知UI修改它,并将UI通知回调添加到绑定到UI的字段中,请参阅