开发者

Toggle two views (Windows) in MVVM WPF

开发者 https://www.devze.com 2023-04-10 13:06 出处:网络
I am developing an application w开发者_开发技巧hich has 2 Modes ConfigurationMode Execution Mode

I am developing an application w开发者_开发技巧hich 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);
        }
    }


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消