Using UWP and MVVM Light, I have a program that uses the same page and ViewModel multiple times with different data. Each page/ViewModel pair is assigned a matching ID so they can more easily reference each other. On the page is a button that shows a ContentDialog.
When opening one of the pages for the first time, the ContentDialog opens properly, but if the page is left and then returned to, calling ShowAsync for ContentDialog causes the very descriptive ArgumentException: 'Value does not fall within the expected range.'
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);
}
Page Code-Behind
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>
My first concern has been that somehow in my setup the showDiag method was being called multiple times. So I've done several tests to know the following:
- The message is being registered once for each ID in the code-behind.
- The message is sent once.
- showDiag is called once.
I'm not sure if this is related, but I found that with this setup the page constructor is being called every time that page is navigated to.