DepartmentProject/DepartmentPortal/Common/DesktopTools/MainControls/GenericControlEntityElement.cs

369 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DesktopTools.BaseControls;
using DesktopTools.Enums;
using DesktopTools.Helpers;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using ModuleTools.Attributes;
using ModuleTools.BindingModels;
using ModuleTools.BusinessLogics;
using ModuleTools.Enums;
using ModuleTools.Extensions;
using ModuleTools.ViewModels;
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Linq;
namespace DesktopTools.Controls
{
public partial class GenericControlEntityElement<G, S, L, E, BL> : MainControlViewEntityElement, IControlViewEntityElement
where G : GetBindingModel, new()
where S : SetBindingModel, new()
where L : ListViewModel<E>
where E : ElementViewModel
where BL : GenericBusinessLogic<G, S, L, E>
{
/// <summary>
/// Объект бизнес-логики для получения данных
/// </summary>
private readonly BL _businessLogic;
/// <summary>
/// Методы для реализации в generic-контроле
/// </summary>
protected IGenericControlEntityElement _genericControlViewEntityElement;
/// <summary>
/// Признак налиичия изменений
/// </summary>
private bool _haveChages = false;
/// <summary>
/// Ширина контрола по умолчанию
/// </summary>
private readonly int _defaultControlWidth = 350;
private E _element = null;
/// <summary>
/// Событие, вызываемое при закрытии контрола
/// </summary>
private event Action<Guid> CloseElementEvent;
/// <summary>
/// События установки одинаковой ширины для заголовков контролов
/// </summary>
private event Action<int> SetTitleWidth;
/// <summary>
/// Событие установки значения
/// </summary>
private event Action<object> SetValues;
/// <summary>
/// Событие сброса значения в исходное состояние
/// </summary>
private event Action DropValues;
/// <summary>
/// Событие проверки заполненности контрола
/// </summary>
private event Func<bool> CheckValues;
/// <summary>
/// Событие получения значения из контрола
/// </summary>
private event Action<object> GetValues;
private E Element
{
get { return _element; }
set
{
try
{
_element = value;
SetValues?.Invoke(_element);
if (tabControl.Visible)
{
foreach (TabPage page in tabControl.TabPages)
{
if (page.Name == tabPageMain.Name)
{
continue;
}
if (page.Controls[0] is IControlChildEntity cntrl)
{
cntrl.ParentId = _element.Id;
cntrl.Open(new ControlOpenModel { OpenMode = ControlOpenMode.Child });
}
}
}
_haveChages = false;
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при установки значений");
}
}
}
public GenericControlEntityElement()
{
InitializeComponent();
InitEvents();
_businessLogic = DependencyManager.Instance.Resolve<BL>();
_controlViewEntityElement = this;
}
public void OpenControl(ControlOpenModel model)
{
if (model.CloseElement != null)
{
CloseElementEvent += model.CloseElement;
}
if (panelContainer.Controls.Count == 0)
{
try
{
Configurate();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при конфигурации");
}
}
if (model.ElementId.HasValue)
{
Element = _businessLogic.GetElement(new G { Id = model.ElementId });
if (Element == null)
{
DialogHelper.MessageException(_businessLogic.Errors, "Ошибки при получении элемента");
}
}
Dock = DockStyle.Fill;
}
public IControl GetInstanceControl() => _genericControlViewEntityElement?.GetInstanceGenericControl();
public string SaveControlToXml() => new XElement("Control",
new XAttribute("Type", GetType().FullName),
new XAttribute("ControlId", ControlId),
new XAttribute("Title", Title)).ToString();
public void LoadControlFromXml(string xml)
{
var control = XElement.Parse(xml).Element("Control");
ControlId = new Guid(control.Attribute("ControlId").Value.ToString());
Title = control.Attribute("Title").Value.ToString();
}
private void InitEvents()
{
toolStripButtonSave.Click += (object sender, EventArgs e) => { Save(); };
toolStripButtonReload.Click += (object sender, EventArgs e) =>
{
if (DialogHelper.MessageQuestion("Отменить все внесенные изменения?") == DialogResult.Yes)
{
try
{
DropValues?.Invoke();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при сбросе значений");
}
}
};
toolStripButtonClose.Click += (object sender, EventArgs e) => {
if (_haveChages && DialogHelper.MessageQuestion("Имеется несохраненные данные, вы действительно хотите закрыть элемент?", "Закрытие элемента") == DialogResult.Yes)
{
if (Save())
{
return;
}
}
CloseElementEvent?.Invoke(ControlId);
Dispose();
};
}
private void Configurate()
{
var attributeClass = typeof(E).GetCustomAttribute<ViewModelControlElementClassAttribute>();
if (attributeClass == null)
{
return;
}
tabControl.Visible = attributeClass.HaveDependenceEntities;
panelContainer.Visible = !attributeClass.HaveDependenceEntities;
Width = attributeClass.Width != 0 ? attributeClass.Width : _defaultControlWidth;
int positionY = 5;
int positionX = 5;
int interval = 15;
int titleWidth = 0;
foreach (var property in typeof(E).GetProperties())
{
var attribute = property.GetCustomAttribute<ViewModelControlElementPropertyAttribute>();
if (attribute != null)
{
AbstractBaseControl control = null;
switch (attribute.ControlType)
{
case ControlType.ControlString:
control = new BaseControlString(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MaxLength);
break;
case ControlType.ControlText:
control = new BaseControlText(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MaxLength, attribute.Height);
break;
case ControlType.ControlInt:
control = new BaseControlInt(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinValue, attribute.MaxValue);
break;
case ControlType.ControlDecimal:
control = new BaseControlDecimal(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinValue,
attribute.MaxValue, attribute.DecimalPlaces);
break;
case ControlType.ControlBool:
control = new BaseControlBool(property.Name, attribute.MustHaveValue, attribute.ReadOnly);
break;
case ControlType.ControlDateTime:
control = new BaseControlDateTime(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinDate,
attribute.MaxDate, attribute.CustomDateFormat);
break;
case ControlType.ControlImage:
control = new BaseControlImage(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.Width, attribute.Height);
break;
case ControlType.ControlEnum:
control = new BaseControlEnum(property.Name, attribute.MustHaveValue, attribute.ReadOnly, property.PropertyType);
break;
case ControlType.ControlGuid:
if (attribute.ControlTypeObject.IsNotEmpty())
{
control = new BaseControlGuid(property.Name, attribute.MustHaveValue, attribute.ReadOnly,
DependencyManager.Instance.Resolve(Type.GetType(attribute.ControlTypeObject)) as IControlEntitySelectable,
property.Name == ParentPropertyName ? ParentId : null);
}
break;
}
if (control == null)
{
continue;
}
var widthTitle = control.SetTitle(attribute.DisplayName);
if (widthTitle > titleWidth)
{
titleWidth = widthTitle;
}
control.OnValueChangeEvent += () => { _haveChages = true; };
SetValues += control.SetValue;
DropValues += control.DropValue;
CheckValues += control.CheckValue;
SetTitleWidth += control.SetTitleWidth;
GetValues += control.GetValue;
control.Location = new System.Drawing.Point(positionX, positionY);
control.Width = Width - positionX * 2 - (tabControl.Visible ? 10 : 0);
control.Anchor = AnchorStyles.Top | AnchorStyles.Left;
if (panelContainer.Visible)
{
control.Anchor |= AnchorStyles.Right;
}
positionY += control.Height + interval;
if (panelContainer.Visible)
{
panelContainer.Controls.Add(control);
}
if (tabControl.Visible)
{
tabPageMain.Controls.Add(control);
}
}
}
SetTitleWidth(titleWidth);
Height = attributeClass.Height != 0 ? attributeClass.Height : positionY;
if (attributeClass.HaveDependenceEntities)
{
var attrDependences = typeof(E).GetCustomAttributes<ViewModelControlElementDependenceEntityAttribute>();
if (attrDependences != null)
{
foreach (var attr in attrDependences)
{
if (DependencyManager.Instance.Resolve(Type.GetType(attr.ControlTypeObject)) is IControlChildEntity control)
{
var cntrl = control.GetInstance() as IControlChildEntity;
cntrl.ParentPropertyName = attr.ParentPropertyName;
//cntrl.Open(null);
var tabPage = new TabPage
{
Location = new System.Drawing.Point(4, 24),
Name = "tabPage",
Padding = new Padding(3),
Size = new System.Drawing.Size(122, 99),
TabIndex = 0,
Text = attr.Title,
UseVisualStyleBackColor = true
};
tabPage.Controls.Add(cntrl as UserControl);
tabControl.TabPages.Add(tabPage);
if (attr.IsActive)
{
tabPage.Select();
}
}
}
}
}
}
private bool Save()
{
if (CheckValues.GetInvocationList().Select(x => (bool)x.DynamicInvoke()).ToList().Any(x => !x))
{
return false;
}
var model = Element == null ? new S() : Mapper.MapToClass<E, S>(Element, true);
try
{
GetValues(model);
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при получении значений");
}
if (model != null)
{
if (Element == null)
{
Element = _businessLogic.Create(model);
}
else
{
Element = _businessLogic.Update(model);
}
if (Element == null)
{
DialogHelper.MessageException(_businessLogic.Errors, "Ошибки при сохранении элемента");
}
_haveChages = false;
DialogHelper.MessageInformation("Сохранение прошло успешно", "Сообщение");
return true;
}
return false;
}
}
}