// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Core.Common.Controls.Views; using Core.Common.Utils.Extensions; using Core.Common.Utils.Reflection; using Ringtoets.Common.Forms.Properties; namespace Ringtoets.Common.Forms.Views { /// /// Base view for selecting calculatable objects and starting calculation for said objects. /// /// The type of the calculatable object. public abstract partial class CalculatableView : UserControl, ISelectionProvider where T : class { private const int calculateColumnIndex = 0; private bool updatingDataSource; public event EventHandler SelectionChanged; /// /// Creates a new instance of . /// protected CalculatableView() { InitializeComponent(); LocalizeControls(); InitializeEventHandlers(); } public abstract object Data { get; set; } public object Selection { get { return CreateSelectedItemFromCurrentRow(); } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); InitializeDataGridView(); } protected override void Dispose(bool disposing) { if (disposing) { components?.Dispose(); } base.Dispose(disposing); } /// /// Updates the data source of the data table based on the . /// protected void UpdateDataGridViewDataSource() { updatingDataSource = true; SetDataSource(); updatingDataSource = false; UpdateCalculateForSelectedButton(); } /// /// Initializes the . /// protected virtual void InitializeDataGridView() { dataGridViewControl.AddCheckBoxColumn(nameof(CalculatableRow.ShouldCalculate), Resources.CalculatableView_Calculate); } /// /// Creates a new object that is used as the object for from /// the currently selected row in the data table. /// /// The newly created object. protected abstract object CreateSelectedItemFromCurrentRow(); /// /// Sets the datasource on the . /// protected abstract void SetDataSource(); /// /// Handles the calculation routine for the currently selected rows. /// protected abstract void CalculateForSelectedRows(); /// /// Gets all the row items from the . /// protected IEnumerable> GetCalculatableRows() { return dataGridViewControl.Rows .Cast() .Select(row => (CalculatableRow) row.DataBoundItem); } /// /// Gets all the selected calculatable objects. /// protected IEnumerable GetSelectedCalculatableObjects() { return GetCalculatableRows().Where(r => r.ShouldCalculate) .Select(r => r.CalculatableObject); } /// /// Validates the calculatable objects. /// /// A validation message in case no calculations can be performed, null otherwise. protected virtual string ValidateCalculatableObjects() { if (!GetCalculatableRows().Any(r => r.ShouldCalculate)) { return Resources.CalculatableViews_No_calculations_selected; } return null; } /// /// Updates the state of the calculation button and the corresponding error provider. /// protected void UpdateCalculateForSelectedButton() { string validationText = ValidateCalculatableObjects(); if (!string.IsNullOrEmpty(validationText)) { CalculateForSelectedButton.Enabled = false; CalculateForSelectedButtonErrorProvider.SetError(CalculateForSelectedButton, validationText); } else { CalculateForSelectedButton.Enabled = true; CalculateForSelectedButtonErrorProvider.SetError(CalculateForSelectedButton, ""); } } private void LocalizeControls() { CalculateForSelectedButton.Text = Resources.CalculatableView_CalculateForSelectedButton_Text; DeselectAllButton.Text = Resources.CalculatableView_DeselectAllButton_Text; SelectAllButton.Text = Resources.CalculatableView_SelectAllButton_Text; ButtonGroupBox.Text = Resources.CalculatableView_ButtonGroupBox_Text; } private void InitializeEventHandlers() { dataGridViewControl.AddCurrentCellChangedHandler(DataGridViewOnCurrentCellChangedHandler); dataGridViewControl.AddCellValueChangedHandler(DataGridViewCellValueChanged); } private void OnSelectionChanged() { SelectionChanged?.Invoke(this, new EventArgs()); } #region Event handling private void DataGridViewCellValueChanged(object sender, DataGridViewCellEventArgs e) { if (!updatingDataSource && e.ColumnIndex == calculateColumnIndex) { UpdateCalculateForSelectedButton(); } } private void DataGridViewOnCurrentCellChangedHandler(object sender, EventArgs e) { if (updatingDataSource) { return; } OnSelectionChanged(); } private void SelectAllButton_Click(object sender, EventArgs e) { SetShouldCalculateForAllRowsAndRefresh(true); } private void DeselectAllButton_Click(object sender, EventArgs e) { SetShouldCalculateForAllRowsAndRefresh(false); } private void SetShouldCalculateForAllRowsAndRefresh(bool newShouldCalculateValue) { GetCalculatableRows().ForEachElementDo(row => row.ShouldCalculate = newShouldCalculateValue); dataGridViewControl.RefreshDataGridView(); UpdateCalculateForSelectedButton(); } private void CalculateForSelectedButton_Click(object sender, EventArgs e) { CalculateForSelectedRows(); } #endregion } }