//******************************************************************************************************// PagedViewModelBase.cs - Gbtc//// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may// not use this file except in compliance with the License. You may obtain a copy of the License at://// http://www.opensource.org/licenses/MIT//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 04/07/2011 - Mehulbhai P Thakkar// Generated original version of source code.// 05/13/2011 - Mehulbhai P Thakkar// Modified CurrentItem.PropertyChanged event handler to virtual so that it can // be overloaded by the derived classes for special handling such as by Measurements.cs// 05/25/2011 - J. Ritchie Carroll// Added load/save/delete event operations to allow for user control interception.// 12/20/2012 - Starlynn Danyelle Gilliam// Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Collections.Specialized;using System.ComponentModel;using System.Linq;using System.Reflection;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Threading;using GSF.Data;using GSF.TimeSeries.UI.Commands; namespace GSF.TimeSeries.UI{ /// <summary> /// Represents an abstract class with paging support which all ViewModel objects derive from. /// </summary> public abstract class PagedViewModelBase<TDataModel, TPrimaryKey> : IViewModel where TDataModel : IDataModel, new() { #region [ Members ] // Events /// <summary> /// Raised when a property on this object has a new value. /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Raised before record load is executed. /// </summary> public event CancelEventHandler BeforeLoad; /// <summary> /// Raised when record has been loaded. /// </summary> public event EventHandler Loaded; /// <summary> /// Raised before record save is executed. /// </summary> public event CancelEventHandler BeforeSave; /// <summary> /// Raised when record has been saved. /// </summary> public event EventHandler Saved; /// <summary> /// Raised before record delete is executed. /// </summary> public event CancelEventHandler BeforeDelete; /// <summary> /// Raised when record has been deleted. /// </summary> public event EventHandler Deleted; // Fields private int m_pageCount, m_currentPageNumber, m_itemsPerPage, m_currentSelectedIndex; private IList<TPrimaryKey> m_itemsKeys; private ObservableCollection<TDataModel> m_currentPage, m_itemsSource; private ObservableCollection<ObservableCollection<TDataModel>> m_pages; private ICommand m_firstCommand, m_previousCommand, m_nextCommand, m_lastCommand; private RelayCommand m_saveCommand, m_deleteCommand, m_clearCommand; private TDataModel m_currentItem; private bool m_propertyChanged; private bool m_autoSave; private bool m_hideMessages; private readonly DispatcherTimer m_timer; private readonly TextBlock m_statusTextBlock; private readonly TsfPopup m_statusPopup; private Func<TPrimaryKey, object> m_sortSelector; private string m_sortMember; private string m_sortDirection; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="PagedViewModelBase{T1,T2}"/> class. /// </summary> /// <param name="itemsPerPage">Integer value to determine number of items per page.</param> /// <param name="autoSave">Boolean value to determine is user changes should be saved automatically.</param> protected PagedViewModelBase(int itemsPerPage, bool autoSave = true) { m_itemsPerPage = itemsPerPage; m_autoSave = autoSave; Initialize(); if (itemsPerPage > 0) Load(); m_timer = new DispatcherTimer(); m_timer.Interval = TimeSpan.FromSeconds(5); m_timer.Tick += m_timer_Tick; m_statusTextBlock = Application.Current.MainWindow.FindName("TextBlockResult") as TextBlock; m_statusPopup = Application.Current.MainWindow.FindName("PopupStatus") as TsfPopup; } #endregion #region [ Properties ] /// <summary> /// Gets or sets current selected index on the UI data grid. /// </summary> public int CurrentSelectedIndex { get { return m_currentSelectedIndex; } set { m_currentSelectedIndex = value; OnPropertyChanged("CurrentSelectedIndex"); } } /// <summary> /// Gets or sets flag that determines if current item property has changed. /// </summary> public bool CurrentItemPropertyChanged { get { return m_propertyChanged; } set { m_propertyChanged = value; } } /// <summary> /// Gets or sets if user changes should be saved automatically. /// </summary> public bool AutoSave { get { return m_autoSave; } set { m_autoSave = value; } } /// <summary> /// Gets a message box to display message to users. /// </summary> public Action<string, string, MessageBoxImage> Popup { get { return (Action<string, string, MessageBoxImage>)((message, caption, messageBoxImage) => MessageBox.Show(Application.Current.MainWindow, message, caption, MessageBoxButton.OK, messageBoxImage)); } } /// <summary> /// Gets message box to request confirmation from users. /// </summary> public Func<string, string, bool> Confirm { get { return (Func<string, string, bool>)((message, caption) => MessageBox.Show(Application.Current.MainWindow, message, caption, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes); } } /// <summary> /// Gets or sets number of items to be displayed per page. /// </summary> public int ItemsPerPage { get { return m_itemsPerPage; } set { m_itemsPerPage = value; } } /// <summary> /// Gets or sets the collection of primary keys retrieved fromt he database. /// </summary> public IList<TPrimaryKey> ItemsKeys { get { return m_itemsKeys; } set { m_itemsKeys = value; } } /// <summary> /// Gets or sets the entire collection retrieved from the database. /// </summary> public ObservableCollection<TDataModel> ItemsSource { get { return m_itemsSource; } set { m_itemsSource = value; OnPropertyChanged("ItemsSource"); GeneratePages(); } } /// <summary> /// Gets or sets the current item displayed in a form for edit. /// </summary> public TDataModel CurrentItem { get { return m_currentItem; } set { if ((object)value != null) { if ((object)m_currentItem != null) m_currentItem.PropertyChanged -= m_currentItem_PropertyChanged; m_currentItem = value; if ((object)m_currentItem != null) m_currentItem.PropertyChanged += m_currentItem_PropertyChanged; OnPropertyChanged("CurrentItem"); // If CurrentItem changes then raise OnPropertyChanged on CanDelete property. // This will help us display or hide certain item based on IsNewItem property value. OnPropertyChanged("CanDelete"); // If CurrentItem changes then raise OnPropertyChanged on IsNewRecord property. // This will help us enable or disable Initialize button where applicable. if ((object)m_currentItem != null) OnPropertyChanged("IsNewRecord"); } } } /// <summary> /// Gets or sets collection displayed on the current page. /// </summary> public ObservableCollection<TDataModel> CurrentPage { get { return m_currentPage; } set { if (m_currentPage != null) m_currentPage.CollectionChanged -= m_currentPage_CollectionChanged; m_currentPage = value; OnPropertyChanged("CurrentPage"); if (m_currentPage != null) { m_currentPage.CollectionChanged += m_currentPage_CollectionChanged; if (m_currentPage.Count > 0) { if (CurrentSelectedIndex < 0 || CurrentSelectedIndex >= m_currentPage.Count) CurrentSelectedIndex = 0; CurrentItem = m_currentPage[CurrentSelectedIndex]; } } } } /// <summary> /// Gets or sets an index of <see cref="CurrentPage"/> to be displayed. /// </summary> public int CurrentPageNumber { get { return m_currentPageNumber; } set { if (m_currentPageNumber != value) CurrentSelectedIndex = 0; m_currentPageNumber = Math.Max(Math.Min(value, m_pageCount), 1); OnPropertyChanged("CurrentPageNumber"); Load(); } } /// <summary> /// Gets or sets total number of pages. /// </summary> public int PageCount { get { return m_pageCount; } set { m_pageCount = value; OnPropertyChanged("PageCount"); } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the first page. /// </summary> public ICommand FirstCommand { get { if (m_firstCommand == null) { m_firstCommand = new RelayCommand ( () => { if (m_pages != null) { CurrentPage = m_pages[0]; SetCurrentPageNumber(1); Load(); } }, () => { return (CurrentPageNumber - 1) < 1 ? false : true; } ); } return m_firstCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the previous page. /// </summary> public ICommand PreviousCommand { get { if (m_previousCommand == null) { m_previousCommand = new RelayCommand ( () => { if (m_pages != null) { SetCurrentPageNumber((CurrentPageNumber - 1) < 1 ? 1 : CurrentPageNumber - 1); CurrentPage = m_pages[CurrentPageNumber - 1]; Load(); } }, () => { return (CurrentPageNumber - 1) < 1 ? false : true; } ); } return m_previousCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the next page. /// </summary> public ICommand NextCommand { get { if (m_nextCommand == null) { m_nextCommand = new RelayCommand ( () => { if (m_pages != null) { SetCurrentPageNumber((CurrentPageNumber + 1) > m_pageCount ? m_pageCount : CurrentPageNumber + 1); CurrentPage = m_pages[CurrentPageNumber - 1]; Load(); } }, () => { return (CurrentPageNumber + 1) > m_pageCount ? false : true; } ); } return m_nextCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the last page. /// </summary> public ICommand LastCommand { get { if (m_lastCommand == null) { m_lastCommand = new RelayCommand ( () => { if (m_pages != null) { CurrentPage = m_pages[m_pageCount - 1]; SetCurrentPageNumber(m_pageCount); Load(); } }, () => { return (CurrentPageNumber + 1) > m_pageCount ? false : true; } ); } return m_lastCommand; } } /// <summary> /// Gets save <see cref="ICommand"/>. /// </summary> public ICommand SaveCommand { get { if (m_saveCommand == null) m_saveCommand = new RelayCommand(Save, () => CanSave); return m_saveCommand; } } /// <summary> /// Gets delete <see cref="ICommand"/>. /// </summary> public ICommand DeleteCommand { getLines 1–500 of 1138. Load more
//****************************************************************************************************** // PagedViewModelBase.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 04/07/2011 - Mehulbhai P Thakkar // Generated original version of source code. // 05/13/2011 - Mehulbhai P Thakkar // Modified CurrentItem.PropertyChanged event handler to virtual so that it can // be overloaded by the derived classes for special handling such as by Measurements.cs // 05/25/2011 - J. Ritchie Carroll // Added load/save/delete event operations to allow for user control interception. // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using GSF.Data; using GSF.TimeSeries.UI.Commands; namespace GSF.TimeSeries.UI { /// <summary> /// Represents an abstract class with paging support which all ViewModel objects derive from. /// </summary> public abstract class PagedViewModelBase<TDataModel, TPrimaryKey> : IViewModel where TDataModel : IDataModel, new() { #region [ Members ] // Events /// <summary> /// Raised when a property on this object has a new value. /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Raised before record load is executed. /// </summary> public event CancelEventHandler BeforeLoad; /// <summary> /// Raised when record has been loaded. /// </summary> public event EventHandler Loaded; /// <summary> /// Raised before record save is executed. /// </summary> public event CancelEventHandler BeforeSave; /// <summary> /// Raised when record has been saved. /// </summary> public event EventHandler Saved; /// <summary> /// Raised before record delete is executed. /// </summary> public event CancelEventHandler BeforeDelete; /// <summary> /// Raised when record has been deleted. /// </summary> public event EventHandler Deleted; // Fields private int m_pageCount, m_currentPageNumber, m_itemsPerPage, m_currentSelectedIndex; private IList<TPrimaryKey> m_itemsKeys; private ObservableCollection<TDataModel> m_currentPage, m_itemsSource; private ObservableCollection<ObservableCollection<TDataModel>> m_pages; private ICommand m_firstCommand, m_previousCommand, m_nextCommand, m_lastCommand; private RelayCommand m_saveCommand, m_deleteCommand, m_clearCommand; private TDataModel m_currentItem; private bool m_propertyChanged; private bool m_autoSave; private bool m_hideMessages; private readonly DispatcherTimer m_timer; private readonly TextBlock m_statusTextBlock; private readonly TsfPopup m_statusPopup; private Func<TPrimaryKey, object> m_sortSelector; private string m_sortMember; private string m_sortDirection; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="PagedViewModelBase{T1,T2}"/> class. /// </summary> /// <param name="itemsPerPage">Integer value to determine number of items per page.</param> /// <param name="autoSave">Boolean value to determine is user changes should be saved automatically.</param> protected PagedViewModelBase(int itemsPerPage, bool autoSave = true) { m_itemsPerPage = itemsPerPage; m_autoSave = autoSave; Initialize(); if (itemsPerPage > 0) Load(); m_timer = new DispatcherTimer(); m_timer.Interval = TimeSpan.FromSeconds(5); m_timer.Tick += m_timer_Tick; m_statusTextBlock = Application.Current.MainWindow.FindName("TextBlockResult") as TextBlock; m_statusPopup = Application.Current.MainWindow.FindName("PopupStatus") as TsfPopup; } #endregion #region [ Properties ] /// <summary> /// Gets or sets current selected index on the UI data grid. /// </summary> public int CurrentSelectedIndex { get { return m_currentSelectedIndex; } set { m_currentSelectedIndex = value; OnPropertyChanged("CurrentSelectedIndex"); } } /// <summary> /// Gets or sets flag that determines if current item property has changed. /// </summary> public bool CurrentItemPropertyChanged { get { return m_propertyChanged; } set { m_propertyChanged = value; } } /// <summary> /// Gets or sets if user changes should be saved automatically. /// </summary> public bool AutoSave { get { return m_autoSave; } set { m_autoSave = value; } } /// <summary> /// Gets a message box to display message to users. /// </summary> public Action<string, string, MessageBoxImage> Popup { get { return (Action<string, string, MessageBoxImage>)((message, caption, messageBoxImage) => MessageBox.Show(Application.Current.MainWindow, message, caption, MessageBoxButton.OK, messageBoxImage)); } } /// <summary> /// Gets message box to request confirmation from users. /// </summary> public Func<string, string, bool> Confirm { get { return (Func<string, string, bool>)((message, caption) => MessageBox.Show(Application.Current.MainWindow, message, caption, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes); } } /// <summary> /// Gets or sets number of items to be displayed per page. /// </summary> public int ItemsPerPage { get { return m_itemsPerPage; } set { m_itemsPerPage = value; } } /// <summary> /// Gets or sets the collection of primary keys retrieved fromt he database. /// </summary> public IList<TPrimaryKey> ItemsKeys { get { return m_itemsKeys; } set { m_itemsKeys = value; } } /// <summary> /// Gets or sets the entire collection retrieved from the database. /// </summary> public ObservableCollection<TDataModel> ItemsSource { get { return m_itemsSource; } set { m_itemsSource = value; OnPropertyChanged("ItemsSource"); GeneratePages(); } } /// <summary> /// Gets or sets the current item displayed in a form for edit. /// </summary> public TDataModel CurrentItem { get { return m_currentItem; } set { if ((object)value != null) { if ((object)m_currentItem != null) m_currentItem.PropertyChanged -= m_currentItem_PropertyChanged; m_currentItem = value; if ((object)m_currentItem != null) m_currentItem.PropertyChanged += m_currentItem_PropertyChanged; OnPropertyChanged("CurrentItem"); // If CurrentItem changes then raise OnPropertyChanged on CanDelete property. // This will help us display or hide certain item based on IsNewItem property value. OnPropertyChanged("CanDelete"); // If CurrentItem changes then raise OnPropertyChanged on IsNewRecord property. // This will help us enable or disable Initialize button where applicable. if ((object)m_currentItem != null) OnPropertyChanged("IsNewRecord"); } } } /// <summary> /// Gets or sets collection displayed on the current page. /// </summary> public ObservableCollection<TDataModel> CurrentPage { get { return m_currentPage; } set { if (m_currentPage != null) m_currentPage.CollectionChanged -= m_currentPage_CollectionChanged; m_currentPage = value; OnPropertyChanged("CurrentPage"); if (m_currentPage != null) { m_currentPage.CollectionChanged += m_currentPage_CollectionChanged; if (m_currentPage.Count > 0) { if (CurrentSelectedIndex < 0 || CurrentSelectedIndex >= m_currentPage.Count) CurrentSelectedIndex = 0; CurrentItem = m_currentPage[CurrentSelectedIndex]; } } } } /// <summary> /// Gets or sets an index of <see cref="CurrentPage"/> to be displayed. /// </summary> public int CurrentPageNumber { get { return m_currentPageNumber; } set { if (m_currentPageNumber != value) CurrentSelectedIndex = 0; m_currentPageNumber = Math.Max(Math.Min(value, m_pageCount), 1); OnPropertyChanged("CurrentPageNumber"); Load(); } } /// <summary> /// Gets or sets total number of pages. /// </summary> public int PageCount { get { return m_pageCount; } set { m_pageCount = value; OnPropertyChanged("PageCount"); } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the first page. /// </summary> public ICommand FirstCommand { get { if (m_firstCommand == null) { m_firstCommand = new RelayCommand ( () => { if (m_pages != null) { CurrentPage = m_pages[0]; SetCurrentPageNumber(1); Load(); } }, () => { return (CurrentPageNumber - 1) < 1 ? false : true; } ); } return m_firstCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the previous page. /// </summary> public ICommand PreviousCommand { get { if (m_previousCommand == null) { m_previousCommand = new RelayCommand ( () => { if (m_pages != null) { SetCurrentPageNumber((CurrentPageNumber - 1) < 1 ? 1 : CurrentPageNumber - 1); CurrentPage = m_pages[CurrentPageNumber - 1]; Load(); } }, () => { return (CurrentPageNumber - 1) < 1 ? false : true; } ); } return m_previousCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the next page. /// </summary> public ICommand NextCommand { get { if (m_nextCommand == null) { m_nextCommand = new RelayCommand ( () => { if (m_pages != null) { SetCurrentPageNumber((CurrentPageNumber + 1) > m_pageCount ? m_pageCount : CurrentPageNumber + 1); CurrentPage = m_pages[CurrentPageNumber - 1]; Load(); } }, () => { return (CurrentPageNumber + 1) > m_pageCount ? false : true; } ); } return m_nextCommand; } } /// <summary> /// Gets <see cref="ICommand"/> for moving to the last page. /// </summary> public ICommand LastCommand { get { if (m_lastCommand == null) { m_lastCommand = new RelayCommand ( () => { if (m_pages != null) { CurrentPage = m_pages[m_pageCount - 1]; SetCurrentPageNumber(m_pageCount); Load(); } }, () => { return (CurrentPageNumber + 1) > m_pageCount ? false : true; } ); } return m_lastCommand; } } /// <summary> /// Gets save <see cref="ICommand"/>. /// </summary> public ICommand SaveCommand { get { if (m_saveCommand == null) m_saveCommand = new RelayCommand(Save, () => CanSave); return m_saveCommand; } } /// <summary> /// Gets delete <see cref="ICommand"/>. /// </summary> public ICommand DeleteCommand { get