2021-04-01 21:30:29 +04:00
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 ;
2021-04-02 09:29:09 +04:00
using System.Xml.Linq ;
2021-04-01 21:30:29 +04:00
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 ;
2021-04-02 09:29:09 +04:00
/// <summary>
/// События установки одинаковой ширины для заголовков контролов
/// </summary>
2021-04-01 21:30:29 +04:00
private event Action < int > SetTitleWidth ;
2021-04-02 09:29:09 +04:00
/// <summary>
/// Событие установки значения
/// </summary>
2021-04-01 21:30:29 +04:00
private event Action < object > SetValues ;
2021-04-02 09:29:09 +04:00
/// <summary>
/// Событие с б р о с а значения в исходное состояние
/// </summary>
2021-04-01 21:30:29 +04:00
private event Action DropValues ;
2021-04-02 09:29:09 +04:00
/// <summary>
/// Событие проверки заполненности контрола
/// </summary>
2021-04-01 21:30:29 +04:00
private event Func < bool > CheckValues ;
2021-04-02 09:29:09 +04:00
/// <summary>
/// Событие получения значения из контрола
/// </summary>
2021-04-01 21:30:29 +04:00
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 )
{
2021-04-02 09:29:09 +04:00
cntrl . ParentId = _element . Id ;
2021-04-01 21:30:29 +04:00
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 ;
}
2021-04-02 09:29:09 +04:00
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 ( ) ;
}
2021-04-01 21:30:29 +04:00
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 ( ) ;
}
}
}
}
}
}
2021-04-02 09:29:09 +04:00
private bool Save ( )
2021-04-01 21:30:29 +04:00
{
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 ;
}
}
}