Monorepo/GUIs.ZooFlow/Administration/ClassDetailPage.vb
2022-03-07 15:51:27 +01:00

368 lines
12 KiB
VB.net

Imports System.ComponentModel
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Controls
Imports DevExpress.XtraLayout
Imports DevExpress.XtraTab
Imports DigitalData.Modules.Language.Utils
Imports DigitalData.Modules.Logging
''' <summary>
'''
''' </summary>
Public Class ClassDetailPageManager
Private ReadOnly LogConfig As LogConfig
Private ReadOnly Logger As Logger
Private ReadOnly HostForm As IAdminForm
Public Items As New Dictionary(Of String, DetailPage)
Public Event AnyControl_Focus As EventHandler(Of DetailPageEventArgs)
Public Event AnyControl_Changed As EventHandler(Of DetailPageEventArgs)
Public Event CurrentPage_Changed As EventHandler(Of DetailPageEventArgs)
Private RaiseChangedEvents As Boolean = True
Private CurrentPage As DetailPage
Public Property Current As DetailPage
Get
Return CurrentPage
End Get
Set(value As DetailPage)
CurrentPage = value
RaiseEvent CurrentPage_Changed(Me, New DetailPageEventArgs With {.Page = CurrentPage})
End Set
End Property
Public Class DetailPageEventArgs
Public Property Page As DetailPage
End Class
''' <summary>
''' An object representing a section of a form to edit an entity, ex. a user
''' </summary>
''' <remarks>A Page to edit would be called the user page.</remarks>
Public Class DetailPage
''' <summary>
''' Is this the primary entity to be edited in this form?
''' </summary>
Public Property IsPrimary As Boolean = False
''' <summary>
''' Is this an insert of a new object?
''' </summary>
''' <returns></returns>
Public Property IsInsert As Boolean = False
''' <summary>
''' The tab page containing the page. This can be left empty
''' </summary>
Public Property TabPage As XtraTabPage = Nothing
''' <summary>
''' The Name of the Page which the user will see
''' </summary>
Public Property Name As String
''' <summary>
''' The Binding Source for the Page
''' </summary>
Public Property BindingSource As BindingSource
''' <summary>
''' The Bound Datatable in the Dataset (eg. MyDataset.TB_FOO_TABLE)
''' </summary>
Public Property DataTable As DataTable
''' <summary>
''' The TextEdit Control containing the AddedWho value
''' </summary>
Public Property AddedWhoEdit As TextEdit
''' <summary>
''' The TextEdit Control containing the ChangedWhoEdit value
''' </summary>
Public Property ChangedWhoEdit As TextEdit
End Class
''' <summary>
''' Detail page which represents the primary page of a form
''' </summary>
Public Class PrimaryPage
Inherits DetailPage
Public Sub New(Insert As Boolean)
IsInsert = Insert
IsPrimary = True
End Sub
End Class
Public Class ComboBoxItem
Public Property Text
Public Property Value
Public Overrides Function ToString() As String
Return Text
End Function
End Class
Public Sub New(LogConfig As LogConfig, Form As IAdminForm, LayoutControls As List(Of LayoutControl))
Me.LogConfig = LogConfig
Logger = LogConfig.GetLogger()
HostForm = Form
For Each oLayoutControl In LayoutControls
AddHandler oLayoutControl.Click, AddressOf Handle_Focus
AddHandler oLayoutControl.GotFocus, AddressOf Handle_Focus
For Each oContainer As BaseLayoutItem In oLayoutControl.Root.Items
Dim oItem As LayoutControlItem
If TypeOf oContainer IsNot LayoutControlItem Then
Continue For
End If
oItem = oContainer
If TypeOf oItem Is EmptySpaceItem Then
Continue For
End If
If TypeOf oItem.Control IsNot BaseEdit Then
Continue For
End If
Dim oControl As BaseEdit = oItem.Control
AddHandler oControl.GotFocus, AddressOf Handle_Focus
AddHandler oControl.EditValueChanged, AddressOf Handle_EditValueChanged
AddHandler oControl.Validating, AddressOf Handle_Validating
Next
'For Each oContainer As LayoutControlItem In oLayoutControl.Root.Items
' If TypeOf oContainer Is EmptySpaceItem Then
' Continue For
' End If
' If TypeOf oContainer.Control IsNot BaseEdit Then
' Continue For
' End If
' Dim oControl As BaseEdit = oContainer.Control
' AddHandler oControl.GotFocus, AddressOf Handle_Focus
' AddHandler oControl.EditValueChanged, AddressOf Handle_EditValueChanged
' AddHandler oControl.Validating, AddressOf Handle_Validating
'Next
Next
End Sub
''' <summary>
''' Add a new DetailPage or a new PrimaryPage
''' </summary>
Public Sub Add(Page As DetailPage)
If Page.TabPage Is Nothing Then
Items.Add("Primary", Page)
Else
Items.Add(Page.TabPage.Name, Page)
End If
AddHandler Page.BindingSource.AddingNew, Sub(sender As Object, e As EventArgs)
RaiseChangedEvents = False
Page.AddedWhoEdit.EditValue = Environment.UserName
RaiseChangedEvents = True
End Sub
End Sub
''' <summary>
''' Add a list of new DetailPages or new PrimaryPages
''' </summary>
Public Sub AddRange(ParamArray Pages As DetailPage())
For Each oPage In Pages
Add(oPage)
Next
End Sub
''' <summary>
''' Get the DetailPage which uses the given `TabPage`
''' </summary>
Public Function GetDetailPage(TabPage As XtraTabPage) As DetailPage
Try
Dim oItem = Items.
Where(Function(Item) TabPage.Equals(Item.Value.TabPage)).
FirstOrDefault()
Return oItem.Value
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function PrepareLoad() As Boolean
Dim oItem = Items.
Where(Function(Item) Item.Value.IsPrimary).
FirstOrDefault()
Dim oPage = oItem.Value
If oPage Is Nothing Then
Return False
End If
If oPage.IsInsert Then
RaiseChangedEvents = False
oPage.BindingSource.AddNew()
RaiseChangedEvents = True
End If
CurrentPage = oPage
Return True
End Function
''' <summary>
''' Saves the pending changes to the binding source
''' </summary>
''' <returns>True, if changes were made, otherwise False</returns>
Public Function PrepareSave() As Boolean
Dim oPage = CurrentPage
If oPage Is Nothing Then
Return False
End If
Try
oPage.BindingSource.EndEdit()
If oPage.DataTable.GetChanges() IsNot Nothing Then
RaiseChangedEvents = False
HostForm.HasChanges = True
If oPage.IsInsert Then
oPage.AddedWhoEdit.EditValue = My.Application.User.UserName
Else
oPage.ChangedWhoEdit.EditValue = My.Application.User.UserName
End If
RaiseChangedEvents = True
oPage.BindingSource.EndEdit()
Return True
Else
Return False
End If
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Private Sub Handle_Validating(sender As Object, e As BaseEditValidatingEventArgs)
Dim oControl As BaseEdit = sender
Dim oColumn As DataColumn = Get_DataColumnFromBaseEdit(oControl)
If oColumn IsNot Nothing Then
Dim oNullable As Boolean = oColumn.AllowDBNull
If oNullable = False Then
If TypeOf oControl Is ComboBoxEdit AndAlso DirectCast(oControl, ComboBoxEdit).SelectedIndex = -1 Then
e.ErrorText = "Please select a value from the list."
e.Cancel = True
ElseIf NotNull(oControl.EditValue.ToString, String.Empty) = String.Empty Then
e.ErrorText = "Please input a value"
e.Cancel = True
End If
End If
End If
End Sub
Private Function Get_DataColumnFromBaseEdit(Control As BaseEdit) As DataColumn
Dim oBinding As Binding = Control.DataBindings.Item("EditValue")
If Control.DataBindings.Count = 0 OrElse oBinding Is Nothing Then
Return Nothing
End If
If oBinding.DataSource Is Nothing Then
Return Nothing
End If
If TypeOf oBinding.DataSource IsNot BindingSource Then
Return Nothing
End If
Try
Dim oSource As BindingSource = oBinding.DataSource
Dim oTableName As String = oSource.DataMember
Dim oDataSet As DataSet = oSource.DataSource
Dim oTable = oDataSet.Tables(oTableName)
Dim oColumnName As String = oBinding.BindingMemberInfo.BindingField
Dim oColumn As DataColumn = oTable.Columns.Item(oColumnName)
Return oColumn
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Sub Handle_Focus(sender As Control, e As EventArgs)
Dim oControl As Control = sender
Dim oLayoutControl As LayoutControl = Nothing
' Get the Layout Control containing the Edit Contol
If TypeOf oControl.Parent Is LayoutControl Then
oLayoutControl = oControl.Parent
ElseIf TypeOf oControl Is LayoutControl Then
oLayoutControl = oControl
End If
If oLayoutControl Is Nothing Then
Exit Sub
End If
If TypeOf oLayoutControl.Parent Is XtraTabPage Then
Dim oTabPage As XtraTabPage = oLayoutControl.Parent
If Items.ContainsKey(oTabPage.Name) Then
CurrentPage = Items.Item(oTabPage.Name)
Dim oData As New DetailPageEventArgs With {.Page = Items.Item(oTabPage.Name)}
RaiseEvent CurrentPage_Changed(Me, oData)
RaiseEvent AnyControl_Focus(oControl, oData)
Else
CurrentPage = Nothing
RaiseEvent CurrentPage_Changed(Me, Nothing)
RaiseEvent AnyControl_Focus(oControl, Nothing)
End If
End If
End Sub
Private Sub Handle_EditValueChanged(sender As BaseEdit, e As EventArgs)
Dim oControl As BaseEdit = sender
If RaiseChangedEvents = False Then
Exit Sub
End If
' Get the Layout Control containing the Edit Contol
If TypeOf oControl.Parent Is LayoutControl Then
Dim oLayoutControl As LayoutControl = oControl.Parent
' Get the TabPage containing the Layout Control
If TypeOf oLayoutControl.Parent Is XtraTabPage Then
Dim oTabPage As XtraTabPage = oLayoutControl.Parent
If Items.ContainsKey(oTabPage.Name) Then
Dim oData As New DetailPageEventArgs With {.Page = Items.Item(oTabPage.Name)}
RaiseEvent AnyControl_Changed(oControl, oData)
Else
RaiseEvent AnyControl_Changed(oControl, Nothing)
End If
End If
End If
End Sub
End Class