Jak na pruvodce nastavenim programu pomoci NavigationWindow


Dneska vam ukazu kousek kodu z programu IlCamminoManager, konkretne jeho pruvodce nastavenim, ktere ma 2 stranky. Mezi temito strankami prochazite tak ze volate metodu this.NavigationService.GoBack() pro prechod pomoci tlacitka zpet a naopak metodu this.NavigationService.Navigate() pro prechod vpred. Navic muzete diky tomu ze cele toto je obalene v objektu NavigationWindow prechazet pomoci dedikovanych tlacitek navigace zpet/vpred. Cele to funguje tak, ze vytvorite obalujici objekt NavigationWindow a k nemu neomezene trid PageFunction, ktera je genericka a jeji typ je ten, ktery chcete vratit do objektu NavigationWindow. Ja zde pouzivam vycet WizardResult s 2mi hodnotami – Cancelled a Finished. Ale ted uz k kodu. Prvni si vytvorime pomocny kod, tedy soubor s delegatem kde staci jediny radek:

public delegate void VoidObject(object o);

Dale je treba si vytvorit jiz zminovany vycet WizardResult(tento vycet musi mit za vsech okolnosti nejakou namespace, kterou pak importujete pomoci xmlns: do xaml souboru. Ja jsem si tento soubor dal do sdileneho sestaveni swf, abych ji mohl pouzivat ve vsech projektech):
namespace swf
{
    public enum WizardResult
    {
        Finished,
        Canceled
    }
}

A nyni uz vam tu budu servirovat objekt SettingsWizard odvozeny od NavigationWindow a zbyle objekty odvozene od PageFunction ve sledu, ve kterem se budou postupne volat. XML dokumentace je take napsana v tomto sledu, takze staci jen cist tyto komentare a budete vedet o co se jedna v nasledujicim kodu. Vzdy prvne uvedu kod XAML a az pote code-behind c#. Zaciname tedy objektem NavigationWindow: SettingsWizard.xaml
<!--Urcite by bylo fajn nastavit lepsi titulek nez SettingsWizard, protoze tento titulek bude mit okno pruvodce v veskery cas.-->
<NavigationWindow x:Class="IlCamminoManager.SettingsWizard" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="SettingsWizard" Height="500" Width="500">
</NavigationWindow> 

SettingsWizard.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace IlCamminoManager
{
    /// <summary>
    /// Jedina spousteci/vstupni komponenta, kterou budeme vytvaret kdyz budeme chtit zobrazit nastavovaci dialog
    /// </summary>
    public partial class SettingsWizard : NavigationWindow
    {
        /// <summary>
        /// Dokud tuto promennou nenastavi metoda launcher_WizardClosing na Finished, pruvodce sice pujde zavrit ale s dotazem predtim zda to chceme skutecne udelat
        /// </summary>
        WizardResult wizardResult = WizardResult.Canceled;
        /// <summary>
        /// Vytvorim objekt SettingsWizardLauncher a zobrazim jej v tomto okne metodou Navigate. Tento objekt ale nema zadne GUI, slouzi pouze pro nastaveni a presmerovani na skutecnou prvni stranku pruvodce.
        /// </summary>
        public SettingsWizard()
        {
            InitializeComponent();
            //-Vytvorim objekt SettingsWizardLauncher a zaregistuji mu udalost WizardClosing, ktera se bude vyvolavat pri kliknuti na tlacitko Finish/Dokoncit pruvodce
            SettingsWizardLauncher launcher = new SettingsWizardLauncher();
            launcher.WizardClosing += launcher_WizardClosing;
            //-Alternativne bychom mohli pouzit Return misto WizardClosing
            //launcher.Return += launcher_Return;
            this.Navigate(launcher);
        }
        /// <summary>
        /// Pokud je A1 WizardResult.Finished, znamena to ze bylo kliknuto na tlacitko Finish
        /// </summary>
        /// <param name="o"> 
        void launcher_WizardClosing(object o)
        {
            wizardResult = (WizardResult)o;
            if (wizardResult == WizardResult.Finished)
            {
                Close();
            }
        }
        /// <summary>
        /// Pokud nebylo kliknuto na tlacitko Finish, zobrazim MessageBox, s dotazem zda chci zavrit okno, protoze nedokonceni pruvodce muze znamenat nefunkcnost programu.
        /// </summary>
        /// <param name="e"> 
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            if (wizardResult != WizardResult.Finished)
            {
                MessageBoxResult b = System.Windows.MessageBox.Show("Unfinishing this wizard app crash during runtime or not be available all functions of app", M.ja, MessageBoxButton.OKCancel);
                if (b == MessageBoxResult.OK)
                {
                    return;
                }
                e.Cancel = true;
            }
        }
    }
}

SettingsWizardLauncher.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Navigation;
namespace IlCamminoManager
{
    /// <summary>
    /// Kazda stranka navigace musi byt odvozena PageFunction. 
    /// Objekty PageFunction se vytvareji vzdy, jak pri prvnim zobrazeni, tak pri prechodu zpet/vpred na nej.
    /// Tato stranka pouze presmeruje na dalsi PageFunction a nebude se na ni dat nikdy jinak jak dostat - ani pres navigaci(protoze nema XAML), ani pres btnBack.
    /// </summary>
    class SettingsWizardLauncher : PageFunction<WizardResult>
    {
        public event VoidObject WizardClosing;
        protected override void Start()
        {
            base.Start();
            //-Patrne, pokud nastavime KeepAlive na True, budeme moci prochazet zpet/vpred ve strankach bez ztraty dat v nich. Toto se ale nas zde netyka, protoze my vzdy v konstruktoru stranky odvozene od PageFunction a
            jejich Controls naplnujeme v konstruktoru kazde takove PageFunction
            //this.KeepAlive = true;
            SettingsWizardFolders settingsWizardFolders = new SettingsWizardFolders();
            settingsWizardFolders.Return += settingsWizardFolders_Return;
            this.NavigationService.Navigate(settingsWizardFolders);
        }
        void settingsWizardFolders_Return(object sender, ReturnEventArgs<WizardResult> e)
        {
            WizardClosing(e.Result);
            OnReturn(null);
        }
    }
} 

SettingsWizardFolders.xaml  

<PageFunction x:Class="IlCamminoManager.SettingsWizardFolders" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:IlCamminoManager" mc:Ignorable="d" x:TypeArguments="local:WizardResult" xmlns:swf="clr-namespace:swf;assembly=swf" Title="Set folders program">

   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="*"> </RowDefinition>
           <RowDefinition Height="35"> </RowDefinition>
       </Grid.RowDefinitions>

       <StackPanel Orientation="Vertical" Grid.Row="0">
           <TextBlock Margin="5,5,20,5" Text="Folders settings" FontSize="25"> </TextBlock>
           <TextBlock x:Name="tbIntroduction" Margin="10" TextWrapping="Wrap"> </TextBlock>

           <TextBlock TextWrapping="Wrap" Text="Folder where you want to store user application files (for example, when you do not want these files on SSD):" Margin="5"> </TextBlock>
           <swf:SelectFolder x:Name="selectFolderWithApplicationFiles"> </swf:SelectFolder>
           
           <TextBlock Text="Folder with *.mp3 of Il Cammino files:" Margin="5"> </TextBlock>
           <swf:SelectFolder x:Name="selectFolderWithMp3IlCamminos"> </swf:SelectFolder>

           <TextBlock Text="Folder with *.txt of Il Cammino tracklist files:" Margin="5"> </TextBlock>
           <swf:SelectFolder x:Name="selectFolderWithTracklistIlCamminos"> </swf:SelectFolder>
           
       </StackPanel>

       <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1">
           <Button Margin="5,5,15,5" HorizontalAlignment="Right" Content=" < Back" x:Name="btnBack" Width="70" Height="25" FontSize="15"> </Button>
           <Button Margin="0,5,0,5" HorizontalAlignment="Right" Content="Next >" Width="70" x:Name="btnNext" Height="25" FontSize="15"> </Button>
           <Button Margin="15,5,5,5" HorizontalAlignment="Right" Content="Finish" Width="70" Height="25" x:Name="btnFinish" FontSize="15"> </Button>
       </StackPanel>
   </Grid>
</PageFunction> 

SettingsWizardFolders.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace IlCamminoManager
{
    /// <summary>
    /// 
    /// </summary>
    public partial class SettingsWizardFolders : PageFunction<WizardResult>
    {
        public SettingsWizardFolders()
        {
            InitializeComponent();
            //-btnBack a btnFinish bude vzdy false, proto jim nemusime registrovat handlery
            btnBack.IsEnabled = false;
            btnNext.IsEnabled = false;
            btnNext.Click += btnNext_Click;
            btnFinish.IsEnabled = false;
            tbIntroduction.Text = "Welcome to the " + M.ja + ". This guide, if you lowered yourself, it's because you lack in setting some items. Please complete this wizard program that could work.";
            selectFolderWithApplicationFiles.FolderChanged += selectFolderWithApplicationFiles_FolderChanged;
            selectFolderWithApplicationFiles.SelectedFolder = IlCamminoManagerSettings.FolderWithApplicationFiles;
            if (selectFolderWithApplicationFiles.SelectedFolder == "")
            {
                selectFolderWithApplicationFiles.SelectedFolder = FA.RootFolder;
            }
            selectFolderWithMp3IlCamminos.FolderChanged += selectFolderWithMp3IlCamminos_FolderSelected;
            selectFolderWithMp3IlCamminos.SelectedFolder = IlCamminoManagerSettings.FolderWithFilesOfIlCammino;
            selectFolderWithTracklistIlCamminos.FolderChanged += selectFolderWithTracklistIlCamminos_FolderSelected;
            selectFolderWithTracklistIlCamminos.SelectedFolder = IlCamminoManagerSettings.FolderWithTracklists;
            DisableEnableBtnNext();
        }
        #region Toto nas moc nemusi zajimat, metody menici nastaveni programu a IsEnabled btnNext
        void selectFolderWithApplicationFiles_FolderChanged(string s)
        {
            IlCamminoManagerSettings.FolderWithApplicationFiles = s;
            FA.RootFolder = s;
            DisableEnableBtnNext();
        }
        void selectFolderWithTracklistIlCamminos_FolderSelected(string s)
        {
            IlCamminoManagerSettings.FolderWithTracklists = s;
            DisableEnableBtnNext();
        }
        void selectFolderWithMp3IlCamminos_FolderSelected(string s)
        {
            IlCamminoManagerSettings.FolderWithFilesOfIlCammino = s;
            DisableEnableBtnNext();
        }
        private void DisableEnableBtnNext()
        {
            FA.CreateAppFoldersIfDontExists();
            btnNext.IsEnabled = IsAllRequiredFilled();
        }
        private bool IsAllRequiredFilled()
        {
            if (
            Directory.Exists(selectFolderWithApplicationFiles.SelectedFolder))
            {
                SetIsEnabledOtherFolderSelects(true);
                if (Directory.Exists(selectFolderWithMp3IlCamminos.SelectedFolder))
                {
                    if (Directory.Exists(selectFolderWithTracklistIlCamminos.SelectedFolder))
                    {
                        return true;
                    }
                }
            }
            else
            {
                SetIsEnabledOtherFolderSelects(false);
            }
            return false;
        }
        private void SetIsEnabledOtherFolderSelects(bool p)
        {
            selectFolderWithMp3IlCamminos.IsEnabled = p;
            selectFolderWithTracklistIlCamminos.IsEnabled = p;
        }
        #endregion
        void btnNext_Click(object sender, RoutedEventArgs e)
        {
            //-Tyto 2 radky muzeme ignorovat
            FA.CreateAppFoldersIfDontExists();
            IlCamminoManagerSettings.ReloadFilePathsOfSettings();
            //-Pokud chci jit na dalsi stranku, musim tento objekt vytvorit vzdy uplne novy...
            SettingsWizardPerformance settingsWizardPerformance = new SettingsWizardPerformance();
            settingsWizardPerformance.Return += settingsWizardPerformance_Return;
            //-...a pak na neho zavolat metodu this.NavigationService.Navigate
            this.NavigationService.Navigate(settingsWizardPerformance);
        }
        /// <summary>
        /// Probublame objekt ReturnEventArgs <WizardResult> vyse, az k objektu SettingsWizard
        /// </WizardResult></summary>
        /// <param name="sender"> 
        /// <param name="e"> 
        void settingsWizardPerformance_Return(object sender, ReturnEventArgs<WizardResult> e)
        {
            OnReturn(e);
        }
    }
} 

SettingsWizardPerformance.xaml
<PageFunction x:Class="IlCamminoManager.SettingsWizardPerformance" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:IlCamminoManager" mc:Ignorable="d" x:TypeArguments="local:WizardResult" xmlns:swf="clr-namespace:swf;assembly=swf" Title="Settings that affect performance">

   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="*"> </RowDefinition>
           <RowDefinition Height="35"> </RowDefinition>
       </Grid.RowDefinitions>

       <StackPanel Orientation="Vertical" Grid.Row="0">
           <TextBlock Margin="5,5,20,5" Text="Performance settings" FontSize="25"> </TextBlock>
           <CheckBox Content="Search during typing" x:Name="chbSearchDuringTyping" Margin="5"> </CheckBox>
           
       </StackPanel>

       <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1">
           <Button Margin="5,5,15,5" HorizontalAlignment="Right" Content=" < Back" x:Name="btnBack" Width="70" Height="25" FontSize="15"> </Button>
           <Button Margin="0,5,0,5" HorizontalAlignment="Right" Content="Next >" Width="70" x:Name="btnNext" Height="25" FontSize="15"> </Button>
           <Button Margin="15,5,5,5" HorizontalAlignment="Right" Content="Finish" Width="70" Height="25" x:Name="btnFinish" FontSize="15"> </Button>
       </StackPanel>
   </Grid>
</PageFunction> 

SettingsWizardPerformance.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace IlCamminoManager
{
    /// <summary>
    /// Interaction logic for SettingsWizardPerformance.xaml
    /// </summary>
    public partial class SettingsWizardPerformance : PageFunction<WizardResult>
    {
        public SettingsWizardPerformance()
        {
            InitializeComponent();
            //-Jsme na posledni strance, muzeme jit zpet nebo dokoncit pruvodce ale nemuzeme jit dopredu
            btnBack.Click += btnBack_Click;
            btnNext.IsEnabled = false;
            btnFinish.Click += btnFinish_Click;
            chbSearchDuringTyping.IsChecked = IlCamminoManagerSettings.SearchDuringTyping;
            chbSearchDuringTyping.Checked += chbSearchDuringTyping_Checked;
        }
        void chbSearchDuringTyping_Checked(object sender, RoutedEventArgs e)
        {
            IlCamminoManagerSettings.SearchDuringTyping = (bool)chbSearchDuringTyping.IsChecked;
        }
        /// <summary>
        /// Zde vytvorime a vratime objekt WizardResult.Finished, ktery pak probubla v ReturnEventArgs <WizardResult> az do objektu SettingsWizard typu NavigationWindow
        /// </WizardResult></summary>
        /// <param name="sender"> 
        /// <param name="e"> 
        void btnFinish_Click(object sender, RoutedEventArgs e)
        {
            OnReturn(new ReturnEventArgs<WizardResult>(WizardResult.Finished));
        }
        void btnBack_Click(object sender, RoutedEventArgs e)
        {
            this.NavigationService.GoBack();
        }
    }
} 


Leave a Reply

Your email address will not be published.