为什么这段 C# 代码会乱序执行?不是 ASYNC(至少我不这么认为)
Why is this C# code executing out of sequence? Not ASYNC (at least I don't think it is)
谁能帮我理解为什么我对 dialogservice 的调用是在 CanNavigateAway 函数返回其值后执行的? (我的目标是警告用户他们即将离开视图而不保存更改。如果他们单击“确定”,则允许导航。我正在使用 MVVM Light。
当我单步执行代码时,它确实到达了对话框服务,但随后在创建对话框之前继续到 CanNavigateAway 的末尾。 CanNavigateAway 方法由 OnNavigatingFrom 调用。
public bool CanNavigateAway()
{
if (!changesSaved && Model.IsModified && !continueNavigation)
{
dialogService.ShowMessage("Are you sure you want to continue?",
"Confirmation",
buttonConfirmText: "Continue", buttonCancelText: "Discard",
afterHideCallback: (confirmed) =>
{
if (confirmed)
{
// User has pressed the "confirm" button.
// ...
continueNavigation = true;
}
else
{
// User has pressed the "cancel" button
// (or has discared the dialog box).
// ...
continueNavigation = false;
}
});
return continueNavigation;
}
}
这是来自 MVVM Light Bindable 页面的 OnNavigatingFrom 方法class:
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
if (!navigableViewModel.CanNavigateAway())
{
e.Cancel = true;
}
}
}
我尝试了一种不同的方法来使对话服务脱离混合,但 showConfirmationDialogAsync 似乎仍然没有及时执行:
public bool CanNavigateAway()
{
continueNavigation = false;
if (!changesSaved && Model.IsModified && !continueNavigation)
{
showConfirmationDialogAsync();
return continueNavigation;
}
private async void showConfirmationDialogAsync()
{
continueNavigation = false;
ContentDialog noSaveConfirmation = new ContentDialog
{
Title = "Warning",
Content = "You have unsaved changes. Are you sure you want to leave this page without saving?",
PrimaryButtonText = "Leave without saving",
SecondaryButtonText = "Stay and finish"
};
ContentDialogResult result = await noSaveConfirmation.ShowAsync();
if (result == ContentDialogResult.Primary)
{
continueNavigation = true;
}
else if (result == ContentDialogResult.Secondary)
{
continueNavigation = false;
}
}
如果您需要用户的响应,None 的解决方案将有效。问题是当代码在导航事件处理程序中时,它在 UI 线程上是 运行 并且用户提示异步运行,因此 UI 可以自由显示对话框给用户。然而,这意味着事件处理程序在用户有机会响应之前完成。
但是,您可以使用变通解决方案。添加标志 bool
字段,如 forceNavigation
。然后在 OnNavigatingFrom
中向用户显示对话框并立即将 Cancel
设置为 true
并向用户显示确认对话框。如果用户说是,则将 forceNavigaiton
设置为 true 并再次手动触发导航。现在它将跳过确认部分并立即导航。
protected async override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
//if navigation is forced, skip all logic
if ( !forceNavigation )
{
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
e.Cancel = true;
//display the dialog to the user, if he says yes, set
//forceNavigation = true; and repeat the navigation (e.g. GoBack, ... )
}
}
}
谁能帮我理解为什么我对 dialogservice 的调用是在 CanNavigateAway 函数返回其值后执行的? (我的目标是警告用户他们即将离开视图而不保存更改。如果他们单击“确定”,则允许导航。我正在使用 MVVM Light。
当我单步执行代码时,它确实到达了对话框服务,但随后在创建对话框之前继续到 CanNavigateAway 的末尾。 CanNavigateAway 方法由 OnNavigatingFrom 调用。
public bool CanNavigateAway()
{
if (!changesSaved && Model.IsModified && !continueNavigation)
{
dialogService.ShowMessage("Are you sure you want to continue?",
"Confirmation",
buttonConfirmText: "Continue", buttonCancelText: "Discard",
afterHideCallback: (confirmed) =>
{
if (confirmed)
{
// User has pressed the "confirm" button.
// ...
continueNavigation = true;
}
else
{
// User has pressed the "cancel" button
// (or has discared the dialog box).
// ...
continueNavigation = false;
}
});
return continueNavigation;
}
}
这是来自 MVVM Light Bindable 页面的 OnNavigatingFrom 方法class:
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
if (!navigableViewModel.CanNavigateAway())
{
e.Cancel = true;
}
}
}
我尝试了一种不同的方法来使对话服务脱离混合,但 showConfirmationDialogAsync 似乎仍然没有及时执行:
public bool CanNavigateAway()
{
continueNavigation = false;
if (!changesSaved && Model.IsModified && !continueNavigation)
{
showConfirmationDialogAsync();
return continueNavigation;
}
private async void showConfirmationDialogAsync()
{
continueNavigation = false;
ContentDialog noSaveConfirmation = new ContentDialog
{
Title = "Warning",
Content = "You have unsaved changes. Are you sure you want to leave this page without saving?",
PrimaryButtonText = "Leave without saving",
SecondaryButtonText = "Stay and finish"
};
ContentDialogResult result = await noSaveConfirmation.ShowAsync();
if (result == ContentDialogResult.Primary)
{
continueNavigation = true;
}
else if (result == ContentDialogResult.Secondary)
{
continueNavigation = false;
}
}
None 的解决方案将有效。问题是当代码在导航事件处理程序中时,它在 UI 线程上是 运行 并且用户提示异步运行,因此 UI 可以自由显示对话框给用户。然而,这意味着事件处理程序在用户有机会响应之前完成。
但是,您可以使用变通解决方案。添加标志 bool
字段,如 forceNavigation
。然后在 OnNavigatingFrom
中向用户显示对话框并立即将 Cancel
设置为 true
并向用户显示确认对话框。如果用户说是,则将 forceNavigaiton
设置为 true 并再次手动触发导航。现在它将跳过确认部分并立即导航。
protected async override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
//if navigation is forced, skip all logic
if ( !forceNavigation )
{
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
e.Cancel = true;
//display the dialog to the user, if he says yes, set
//forceNavigation = true; and repeat the navigation (e.g. GoBack, ... )
}
}
}