我使用MVVM创build了一个WPF应用程序,并且在closures/打开窗口时遇到了困难。 在我的login窗口中,我使用以下方法closureslogin窗口,然后使用button单击button打开WindowOPHome窗口:
WindowOPHome dashboard = new WindowOPHome(); dashboard.Show(); Application.Current.MainWindow.Close();
一切工作正常,login窗口在WindowOPHome窗口打开时closures。 当我尝试closuresWindowOPHome窗口并使用类似于login窗口/ WindowOPHome操作的button打开WindowMainAdmin窗口时,WindowMainAdmin窗口打开一秒钟,然后在WindowOPHome永远不见的情况下消失。 以下是closuresWindowOPHome并打开WindowMainAdmin的代码:
WindowMainAdmin dashboard = new WindowMainAdmin(); dashboard.Show(); Application.Current.MainWindow.Close();
任何帮助将不胜感激! 请让我知道是否有任何其他您需要的代码。 非常感谢!
我建议你明确关闭你想要关闭的窗口,而不是假设它是当前的主窗口。
有了MVVM,有很多不同的方法可以做到这一点,您可以使用附加的行为或通过命令参数将窗口传递给视图模型,如下所示:
在按钮xaml中查看:
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
在视图模型中的命令execute方法中:
if (parameter is System.Windows.Window) { WindowMainAdmin dashboard = new WindowMainAdmin(); dashboard.Show(); (parameter as System.Windows.Window).Close(); }
。
或者,你可以迭代所有的窗口,直到找到你想要的。
foreach( Window window in Application.Current.Windows ) { if(window is WindowOPHome) { window.Close(); break; } }
如果您需要打开多个窗口实例,则可能需要检查其他某个属性,而不是仅关闭该类型的第一个属性。
你甚至可以把它变成每个窗口类中的静态关闭方法。
我想当你创建管理窗口,程序认为你的管理窗口是当前主窗口,并关闭它。 为了避免这种情况,你可以明确地关闭你想要的窗口。 我建议实施一个MainViewModel来管理你所有的窗口。 这个例子假设你只想要打开一个窗口。
在视图(任何窗口)中:
private void OnClose(object sender, RoutedEventArgs e) { //ICommand Implemnation that informs MainViewModel of UserInput //In this case, the command ShowOPHome is an Enum inputhandler.Execute(MyCommands.ShowOPHome); }
在ViewModel中:
BaseWindow dashboard; .... public void ShowWindow(MyCommands Param) { //Verify Parameter .... if(!(dashboard is null)) dashboard.Close(); switch(Param) { case MyCommands.ShowOPHome: dashboard = new WindowOPHome(); break; case MyCommands.ShowMainAdmin: dashboard = new WindowMainAdmin(); break; } dashboard.Show(); }
InputHandler:
public class Inputhandler : ICommand { ... public class Execute(object Data) { ... mainViewModel.ShowWindow(MyCommands.ShowOPHome); ... } ... }
你可以使用一些辅助类来创建一个MVVM纯解决方案来解决这个问题
public static class ViewCloser { public static readonly DependencyProperty DialogResultProperty = DependencyProperty.RegisterAttached( "DialogResult", typeof(bool?), typeof(ViewCloser), new PropertyMetadata(DialogResultChanged)); private static void DialogResultChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) { var view = target as Window; if (view == null) return; if (view.IsModal()) view.DialogResult = args.NewValue as bool?; else view.Close(); } public static void SetDialogResult(Window target, bool? value) { target.SetValue(DialogResultProperty, value); } } public static class WindowExtender { public static bool IsModal(this Window window) { var fieldInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic); return fieldInfo != null && (bool)fieldInfo.GetValue(window); } }
在应用程序中,首先在ViewModel中创建一个属性
private bool? _viewClosed; public bool? ViewClosed { get { return _viewClosed; } set { _viewClosed = value); RaisePropertyChanged("ViewClosed"); } }
然后使用我们的helper类在View中绑定它。
<Window x:Class=" ... vhelpers:ViewCloser.DialogResult="{Binding ViewClosed}" ... >
所有这些都是很好的解决方案! 我选择cjmurph的解决方案,因为它非常简单(对于我的软弱的头脑),我可以很容易地适应未来的用途。 请参阅下面的代码。 再次感谢大家!
XAML
Command="{Binding BtnMainAdminPageGO}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
WindowOPMainViewModel
private ICommand _btnMainAdminPage; public ICommand BtnMainAdminPageGO { get { if (_btnMainAdminPage == null) { _btnMainAdminPage = new RelayCommand(param => this.BtnMainAdminPage(), null); } return _btnMainAdminPage; } } private void BtnMainAdminPage() { WindowMainAdmin dashboard = new WindowMainAdmin(); dashboard.Show(); foreach(Window window in Application.Current.Windows) { if (window is WindowOPHome) { window.Close(); break; } } }