使用UWP和MVVM Light,我有一个程序使用相同的页面和ViewModel多次使用不同的数据。每个页面/ ViewModel对都分配有一个匹配的ID,因此它们可以更轻松地相互引用。在页面上是显示ContentDialog的按钮。
第一次打开其中一个页面时,ContentDialog会正确打开,但是如果离开页面然后返回到该页面,则调用ShowAsync for ContentDialog会引起非常描述性的ArgumentException:'值不在预期范围内。'
ViewModel
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();
}
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 _isInit = false;
public MyPage()
{
this.InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back || _isInit)
return;
// Do Somethings...
_isInit = true;
}
当页面被缓存时,它保持页面的当前状态,这意味着两件事:
ContentDialog
不会被新创建页面的ContentDialog
替换,从而导致错误。最诚挚的问候。