// 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
}
}