View model for the Settings view.
Inheritance: BaseViewModel
        /// <summary>
        /// Constructs a new Settings view with the given view model, and with the provided
        /// AddCategoryControl control. The AddCategoryControl instance is not actually displayed
        /// within the Settings view at all, but rather the Settings view internally finds its parent
        /// window and shows this instance of AddCategoryControl within a flyout. This is part of the
        /// reason why the control is supplied.
        ///
        /// The real reason is that presently, there is not a better solution to the problem where
        /// the AddCategoryControl needs to hold a reference to the Engine instance that it is
        /// creating categories for. Handing off this instance to this view or view model, then
        /// passing it up to an internally created instance of AddCategoryControl seems like a worse
        /// solution than this. Doing it this way, the AddCategoryControl instance is kept neatly
        /// together with associated objects at the App code behind level. However, XXX TODO, find a
        /// more elegant solution to this.
        /// </summary>
        /// <param name="viewModel">
        /// The settings view model.
        /// </param>
        /// <param name="addCategoryControl">
        /// The user control that generates, by user input, new FilteringCategory instances.
        /// </param>
        /// <exception cref="ArgumentException">
        /// In the event that either the supplied SettingsViewModel or AddCategoryControl instances
        /// are null, will throw ArgumentException.
        /// </exception>
        public Settings(SettingsViewModel viewModel, AddCategoryControl addCategoryControl)
        {
            InitializeComponent();

            m_viewModel = viewModel;

            if (m_viewModel == null)
            {
                throw new ArgumentException("Expected valid instance of SettingsViewModel");
            }

            m_addCategoryControl = addCategoryControl;

            if (m_addCategoryControl == null)
            {
                throw new ArgumentException("Expected valid instance of AddCategoryControl");
            }

            DataContext = m_viewModel;

            // The control handles input, validation and creation of objects independently, so we
            // simply display the control to the user and listen for any events where a category was
            // successfully created.
            m_addCategoryControl.CategoryCreated += OnFilteringCategoryCreated;

            m_btnDeleteCategory.Click += OnDeleteCategoryClicked;
            m_btnShowAddCategory.Click += OnShowAddCategoryClicked;

            m_regexDigitOnlyValidation = new Regex("[^0-9]");
            m_regexDollarValueOnlyValidation = new Regex("[^0-9\\.]");
        }
Example #2
0
        /// <summary>
        /// Inits all the various views for the application, which will be pushed and popped on the
        /// primary window as requested or required.
        /// </summary>
        private void InitViews()
        {
            if (m_filteringEngine == null)
            {
                throw new Exception("Engine must be initialized prior to initializing views, as views require references to allow user control.");
            }

            // We null check, because if the save state load worked, these conditions will be
            // false and we won't overwrite our restored state.

            // This collection is initialized here because it has a direct connection to the UI.
            if (m_filteredApplicationsTable == null)
            {
                m_filteredApplicationsTable = new ConcurrentDictionary<string, FilteredAppModel>();
            }

            if (m_modelDashboard == null)
            {
                m_modelDashboard = new DashboardModel(m_filteringEngine);
            }

            if (m_viewModelDashboard == null)
            {
                m_viewModelDashboard = new DashboardViewModel(m_modelDashboard);
            }

            if (m_modelStatistics == null)
            {
                m_modelStatistics = new StatisticsModel();
            }

            if (m_viewModelStatistics == null)
            {
                m_viewModelStatistics = new StatisticsViewModel(m_modelStatistics);
            }

            if (m_modelSettings == null)
            {
                m_modelSettings = new SettingsModel();
            }

            if (m_viewModelSettings == null)
            {
                m_viewModelSettings = new SettingsViewModel(m_modelSettings);
            }

            if(m_viewModelWaste == null)
            {
                m_viewModelWaste = new WasteViewModel(m_viewModelSettings, m_viewModelDashboard);
            }

            // Necessary because we use a background worker. This thread != UI thread.
            Current.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                (Action)delegate ()
                {
                    m_modelStatistics.FilterCategories = m_filteringCategoriesObservable;
                    m_modelSettings.FilterCategories = m_filteringCategoriesObservable;

                    m_primaryWindow = new MainWindow();
                    m_viewProgressWait = new ProgressWait();
                    m_viewStatistics = new Statistics(m_viewModelStatistics);
                    m_viewDashboard = new Dashboard(m_viewModelDashboard);
                    m_viewSettings = new Settings(m_viewModelSettings, new AddCategoryControl(m_filteringEngine));
                    m_viewWaste = new Waste(m_viewModelWaste);

                    m_primaryWindow.ViewChangeRequest += OnViewChangeRequest;
                    m_viewDashboard.ViewChangeRequest += OnViewChangeRequest;
                    m_viewStatistics.ViewChangeRequest += OnViewChangeRequest;
                    m_viewSettings.ViewChangeRequest += OnViewChangeRequest;
                    m_viewWaste.ViewChangeRequest += OnViewChangeRequest;

                    // Listen for the statistics view requests for app-wide stats deletion.
                    m_viewStatistics.ClearStatisticsRequested += OnClearAllStatsRequest;

                    MainWindow = m_primaryWindow;
                }
            );
        }        
Example #3
0
        /// <summary>
        /// Loads the models, if present, from their serialized JSON files.
        /// </summary>
        private void LoadProgramState()
        {
            var stateOutputDir = AppDomain.CurrentDomain.BaseDirectory + @"User\";

            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.Converters.Add(new FilteringCategoryConverter(m_filteringEngine));
            settings.Converters.Add(new DashboardConverter(m_filteringEngine));
            settings.Converters.Add(new FilteredAppConverter());

            // This thread != UI thread.

            Current.Dispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                (Action)delegate ()
                {
                    if (m_filteringCategoriesObservable == null)
                    {
                        m_filteringCategoriesObservable = new ObservableCollection<CategorizedFilteredRequestsViewModel>();
                    }
                }
            );

            // Restore filtering categories.
            if (File.Exists(stateOutputDir + "FilterCategories.json"))
            {
                var filterCatsSerialized = File.ReadAllText(stateOutputDir + "FilterCategories.json");

                var filteringCatsList = JsonConvert.DeserializeObject<List<FilteringCategory>>(filterCatsSerialized, settings);

                foreach (var filteringList in filteringCatsList)
                {
                    // Ensure lists are up to date.
                    try
                    {
                        filteringList.UpdateAndLoad();

                        Current.Dispatcher.BeginInvoke(
                            System.Windows.Threading.DispatcherPriority.Normal,
                            (Action)delegate ()
                            {
                                m_filteringCategoriesObservable.Add(new CategorizedFilteredRequestsViewModel(filteringList));
                            }
                        );
                    }
                    catch (Exception err)
                    {
                        m_logger.Error("Error while updating filtering list: {0}.", err.Message);
                    }
                }
            }

            // Restore dashboard stats.
            if (File.Exists(stateOutputDir + "Dashboard.json"))
            {
                var dashboardSerialized = File.ReadAllText(stateOutputDir + "Dashboard.json");

                m_modelDashboard = JsonConvert.DeserializeObject<DashboardModel>(dashboardSerialized, settings);
                m_viewModelDashboard = new DashboardViewModel(m_modelDashboard);
            }

            // Restore settings.
            if (File.Exists(stateOutputDir + "Settings.json"))
            {
                var settingsSerialized = File.ReadAllText(stateOutputDir + "Settings.json");

                m_modelSettings = JsonConvert.DeserializeObject<SettingsModel>(settingsSerialized, settings);
                m_viewModelSettings = new SettingsViewModel(m_modelSettings);
            }

            // Restore filtered apps.
            if (File.Exists(stateOutputDir + "FilteredApps.json"))
            {
                var filteredAppsSerialized = File.ReadAllText(stateOutputDir + "FilteredApps.json");

                m_filteredApplicationsTable = JsonConvert.DeserializeObject<ConcurrentDictionary<string, FilteredAppModel>>(filteredAppsSerialized, settings);

                foreach (var entry in m_filteredApplicationsTable)
                {
                    m_logger.Info(entry.Key);
                    Current.Dispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Normal,
                        (Action)delegate ()
                        {
                            m_viewModelDashboard.FilteredApplications.Add(new FilteredAppViewModel(entry.Value));
                        }
                    );
                }
            }
        }
        /// <summary>
        /// Constructs a new WasteViewModel instance.
        /// </summary>
        /// <param name="settingsViewModel">
        /// The SettingsViewModel from which to receive updated user input about waste calculations.
        /// </param>
        /// <param name="dashboardViewModel">
        /// The m_dashboardViewModelViewModel from which to receive updated blocking statistics.
        /// </param>
        /// <exception cref="ArgumentException">
        /// In the event that the arguments provided are null, will throw ArgumentException.
        /// </exception>
        public WasteViewModel(SettingsViewModel settingsViewModel, DashboardViewModel dashboardViewModel)
        {
            m_settingsViewModel = settingsViewModel;
            m_dashboardViewModel = dashboardViewModel;

            if (m_settingsViewModel == null)
            {
                throw new ArgumentException("Expected valid instance of SettingsViewModel");
            }

            if (m_dashboardViewModel == null)
            {
                throw new ArgumentException("Expected valid instance of m_dashboardViewModelViewModel");
            }

            // Simply subscribe to the property changed events of these view models, and replicate
            // the same change event for mirrored data members.
            m_dashboardViewModel.PropertyChanged += OnLinkedPropertiesChanged;
            m_settingsViewModel.PropertyChanged += OnLinkedPropertiesChanged;
        }