在 MVVM WPF 中切换两个视图 (Windows)

发布于 2024-12-08 12:07:36 字数 3689 浏览 0 评论 0原文

我正在开发一个具有 2 种模式的应用程序

  1. 配置模式
  2. 执行模式

两种模式都将在新窗口中打开。我已经做好了配置窗口。

我需要通过按 Key F12 或类似的东西在两种模式之间切换....此外,我还必须在从执行模式切换到配置模式时提示用户输入密码(仅在会话期间一次)已经制作了密码屏幕并在配置中实现。

我也担心,因为我使用了 Messenger(Meaditor 模式),所以关闭和打开 2 个不同的窗口将再次注册代表......并且我正在启动模态窗口

另外,我们是否需要保持两个视图都处于活动状态,或者我可以在切换时杀死其中一个视图。

对实现完全困惑......

我的 App.Xaml 代码

 /// <summary>
    ///   Application_Startup
    /// </summary>
    /// <param name = "sender"></param>
    /// <param name = "e"></param>
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        log.Debug("Application_Startup  " + Utility.FUNCTION_ENTERED_LOG);
        try
        {

                if (e.Args.Length == 0)
                {
                    AboutDialog.SpashScreen(Utility.TOOL_NAME,
                                            Utility.TOOL_VERSION);
                    MainView mainForm = new MainView();
                    mainForm.ShowDialog();
                }
                else
                {
                    string key = null;
                    foreach (string arg in e.Args)
                    {
                        if (arg.StartsWith("-"))
                        {
                            //this is a key         
                            key = arg;
                            if (key.Equals("-config"))
                            {
                                CommandLineArgs.Add(key, "config");
                                break;
                            }
                            if (key.Equals("-start"))
                            {
                                CommandLineArgs.Add(key, "start");
                            }
                        }
                        else
                        {
                            //should be a value        
                            if (key == null)
                            {
                                throw new Exception(
                                    "The command line arguments are malformed.");
                            }
                            CommandLineArgs.Add(key, arg);
                            key = null;
                        }
                    }
                    string config = string.Empty;
                    foreach (object k in App.CommandLineArgs.Keys)
                    {
                        config += CommandLineArgs[k].ToString();
                    }

                    switch (config)
                    {
                        case "config":
                            AboutDialog.SpashScreen(
                                Utility.TOOL_NAME,
                                Utility.TOOL_VERSION);
                            MainView mainForm = new MainView();
                            mainForm.ShowDialog();
                            break;
                         case "start" :
                               ExecutionForm execuForm= new ExecutionForm();
                               execuForm.ShowDialog();
                               break;
                        default:
                            MessageBox.Show("Incorrect Parameters",
                                            Utility.TOOL_NAME);
                            Application.Current.Shutdown();
                            break;
                    }

            }
            log.Debug("Application_Startup" + Utility.FUNCTION_EXIT_LOG);
        }
        catch (Exception ex)
        {              
            log.Error("Application_Startup" + ex.Message, ex);
        }
    }

I am developing an application which has 2 Modes

  1. Configuration Mode
  2. Execution Mode

Boths modes will open in new window. I have already made the configuration Window.

I need to switch between 2 Modes by pressing Key F12 or something like that.... also i have to prompt the user for password while switching from Execution to configutation mode (Just once durnig the session) i have made the password screen and implemented in configuration.

I am also worried as i have used Messenger(Meaditor pattern) so closing and opening of 2 different windows will register the delegates again nad again... and i am launching Modal windows.

Also do we need to keep both the Views alive or i can kill one of them on toggling.

Totally confused about the implementation...

My App.Xaml Code

 /// <summary>
    ///   Application_Startup
    /// </summary>
    /// <param name = "sender"></param>
    /// <param name = "e"></param>
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        log.Debug("Application_Startup  " + Utility.FUNCTION_ENTERED_LOG);
        try
        {

                if (e.Args.Length == 0)
                {
                    AboutDialog.SpashScreen(Utility.TOOL_NAME,
                                            Utility.TOOL_VERSION);
                    MainView mainForm = new MainView();
                    mainForm.ShowDialog();
                }
                else
                {
                    string key = null;
                    foreach (string arg in e.Args)
                    {
                        if (arg.StartsWith("-"))
                        {
                            //this is a key         
                            key = arg;
                            if (key.Equals("-config"))
                            {
                                CommandLineArgs.Add(key, "config");
                                break;
                            }
                            if (key.Equals("-start"))
                            {
                                CommandLineArgs.Add(key, "start");
                            }
                        }
                        else
                        {
                            //should be a value        
                            if (key == null)
                            {
                                throw new Exception(
                                    "The command line arguments are malformed.");
                            }
                            CommandLineArgs.Add(key, arg);
                            key = null;
                        }
                    }
                    string config = string.Empty;
                    foreach (object k in App.CommandLineArgs.Keys)
                    {
                        config += CommandLineArgs[k].ToString();
                    }

                    switch (config)
                    {
                        case "config":
                            AboutDialog.SpashScreen(
                                Utility.TOOL_NAME,
                                Utility.TOOL_VERSION);
                            MainView mainForm = new MainView();
                            mainForm.ShowDialog();
                            break;
                         case "start" :
                               ExecutionForm execuForm= new ExecutionForm();
                               execuForm.ShowDialog();
                               break;
                        default:
                            MessageBox.Show("Incorrect Parameters",
                                            Utility.TOOL_NAME);
                            Application.Current.Shutdown();
                            break;
                    }

            }
            log.Debug("Application_Startup" + Utility.FUNCTION_EXIT_LOG);
        }
        catch (Exception ex)
        {              
            log.Error("Application_Startup" + ex.Message, ex);
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗弃M 2024-12-15 12:07:36

在我看来,你的实现并不完全错误。

如果我需要通过按键在模态窗口上的两个视图之间切换,那么我就会采用 MVVM 方式...

  1. 使用单个模态窗口来托管多个内容。
  2. 窗口上有一个ContentControl。将 Content 绑定到 DataContext

    
        <菜单 DockPanel.Dock="顶部" ...>
        
         >
    
    
  3. 创建两个数据模板作为资源。一个数据模板对应“配置”视图,另一个数据模板对应“执行”视图。

    ;
         
         
    
    

您可以将这些数据模板保存在不同的资源文件中,并将资源字典合并到窗口资源中。

  1. 创建单个 ViewModel实现了可写的 Mode 属性。

    公共类 ViewModel :INotifPropertyChanged
    {
        私有字符串模式;
    
        公共字符串模式
        {
             获取{ 返回模式; }
             设置{模式=值; NotifPropertyChanged(“模式”); }
        }
    
        私有 IComamnd 更改模式命令;
    
        公共 ICommand 更改模式命令
        {
            得到
            {
                if (changeModeCommand == null)
                     改变模式命令
                        = 新的委托命令(
                             模式改变时,
                             可以模式改变);
                返回更改模式命令;
            }
        }
    
        //// 其他属性和函数放在这里...
    }
    

在上面的代码中,DelegateCommand 并未在 .Net API 内部找到。从互联网上获取它们的实现。

  1. 为窗口上的F12注册一个KeyBinding。 F12 KeyBindingCommand 来自 ViewModel

    ;
        
    
    

在 .Net 4.0 之前的版本中,Command 属性不可绑定。为此,请使用 CommandReference

  1. OnModeChange() 对于 F12 键,从 ViewModel 类切换 Mode 并引发属性更改通知。

  2. Window 上的ContentControl 上有数据触发器。在数据触发器中,检查 Mode 是否为“Config”,并将 ContentTemplate 更改为“Config”数据模板,否则更改为“Execution”数据模板。

     
        
            
            
        
      
    

我希望我的方法在某种意义上对你有帮助。

Your implementation doesnt look totally wrong to me.

If I am given a requirement to swtich between two views on a modal window by a key press then I would have gone the MVVM way...

  1. Use single modal window that hosts multiple contents situationally.
  2. Have a ContentControl on the Window. Bind the Content to the DataContext.

    <DockPanel LastChildFill="true">
        <Menu DockPanel.Dock="Top" ...>
        </Menu>
        <ContentControl Content="{Binding}" ... />
    </DockPanel>
    
  3. Create two data templates as resources. One data template corresponds to the view of "Config" and other data template is for 'Execution" view.

    <Window.Resources>
         <DataTemplate x:Key="ConfigView" ... />
         <DataTemplate x:Key="ExecutionView" ... />
    </Window.Resources>
    

You can keep these data templates in different resources files and merge the resource dictionaries to the window resources.

  1. Create a single ViewModel with a writeable Mode property. Have INotifyPropertyChanged implemented.

    public class ViewModel : INotifPropertyChanged
    {
        private string mode;
    
        public string Mode
        {
             get  { return mode; }
             set  { mode = value; NotifPropertyChanged("Mode"); }
        }
    
        private IComamnd changeModeCommand;
    
        public ICommand ChangeModeCommand
        {
            get
            {
                if (changeModeCommand == null)
                     changeModeCommand
                        = new DelegateCommand(
                             OnModeChange,
                             CanModeChange);
                return changeModeCommand;
            }
        }
    
        //// Other properties and functions go here ...
    }
    

In the code above DelegateCommand is not internally found in .Net APIs. Get their implementation from the internet.

  1. Register a KeyBinding for F12 on the window. The Command for F12 KeyBinding comes from the ViewModel.

    <Window.InputBindings>
        <KeyBinding Command="{Binding ChangeModeCommand}"
                    Key="F12" />
    </Window.InputBindings>
    

In versions prior to .Net 4.0, the Command property is not bindable. use CommandReference for this.

  1. OnModeChange() for F12 key, switch the Mode from ViewModel class and raise property changed Notification.

  2. Have data triggers on the ContentControl on the Window. In the data triggers check Mode if it is "Config" and change the ContentTemplate to "Config" data template othwerise change to "Execution" datatemplate.

       <ContentControl Content="{Binding}">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Mode}" Value="Config">
                        <Setter Property="ContentTemplate"
                                Value="{StaticResource ConfigView}"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Mode}" Value="Execution">
                        <Setter Property="ContentTemplate"
                                Value="{StaticResource ExecutionView}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
      </ContentControl>
    

I hope my way helps you in some sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文