我有一个应用程序,要求用户在对话框中输入SQL连接信息。当用户单击“连接”按钮时,我await
使用提供的凭据SqlConnection.OpenAsync()
的结果,以便在关闭对话框之前测试它们是否有效。我还禁用了“连接”按钮以避免重复尝试。凭据正确时,它几乎立即返回,但如果不是,则最多可能需要30秒才能返回。取消按钮可以使用CancellationToken
取消请求并关闭对话框。
问题是用户仍然可以单击对话框上的窗口关闭按钮来关闭它。我的视图模型未收到通知,但表单仍然关闭。大约30秒左右,连接尝试返回错误信息,并显示一个消息框。
当表单以这种方式关闭时,是否有一个好的MVVM友好方式取消与CancelationToken
的连接尝试?我知道我可以在对话框的代码隐藏中使用一些东西,但是我想避免从那里引用视图模型。
答案 0 :(得分:2)
根据您对MVVM基础架构的使用情况,您可以在Window.Closing
上使用MVVM Light EventToCommand
之类的内容。您可以将此事件绑定到已附加到按钮的取消命令。
有关实现此目的的方法,请参阅MVVM Light: Adding EventToCommand in XAML without Blend, easier way or snippet?。
答案 1 :(得分:1)
尝试等待SqlConnection.OpenAsync()的结果并传入取消令牌。
答案 2 :(得分:1)
您可以为此编写扩展方法。
所以你有一个课程(让我们称之为WindowExtensions)你所附属性的定义。
internal class WindowExtensions
{
public static readonly DependencyProperty WindowClosingCommandProperty = DependencyProperty.RegisterAttached(
"WindowClosingCommand", typeof (ICommand), typeof (WindowExtensions), new PropertyMetadata(null, OnWindowClosingCommandChanged));
private static void OnWindowClosingCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Window window = d as Window;
if (window == null)
return;
if (e.NewValue != null)
{
window.Closing += WindowOnClosing;
}
}
private static void WindowOnClosing(object sender, CancelEventArgs e)
{
Window window = sender as Window;
if (window == null)
return;
ICommand windowClosingCommand = GetWindowClosingCommand(window);
windowClosingCommand.Execute(e);
}
public static void SetWindowClosingCommand(DependencyObject element, ICommand value)
{
element.SetValue(WindowClosingCommandProperty, value);
}
public static ICommand GetWindowClosingCommand(DependencyObject element)
{
return (ICommand) element.GetValue(WindowClosingCommandProperty);
}
}
在Window-Element上的XAML中,您可以将附加属性映射到ViewModel中的ICommand-Property,如:
nameSpaceOfWindowExtensions:WindowExtensions.WindowClosingCommand="{Binding WindowClosingCommand}"
在您的ViewModel中,您有一个ICommand
- 属性,您可以在其中处理它。
类似的东西:
private ICommand windowClosingCommand;
public ICommand WindowClosingCommand
{
get { return windowClosingCommand ?? (windowClosingCommand = new RelayCommand(OnWindowClosing)); }
}
private void OnWindowClosing(object parameter)
{
CancelEventArgs cancelEventArgs = parameter as CancelEventArgs;
if (cancelEventArgs != null)
{
// If you want to cancel the closing of the window you can call the following:
//cancelEventArgs.Cancel = true;
}
}
如果您不需要ViewModel中的CancelEventArgs,只需修改附加属性中的以下行:
windowClosingCommand.Execute(e);
到
windowClosingCommand.Execute(null);