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 ''' ''' ''' Public Class ClassDetailPages 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 Public Class DetailPage Public Property IsPrimary As Boolean = False Public Property IsInsert As Boolean = False Public Property TabPage As XtraTabPage Public Property Name As String Public Property BindingSource As BindingSource Public Property DataTable As DataTable Public Property AddedWhoEdit As TextEdit Public Property ChangedWhoEdit As TextEdit End Class ''' ''' Detail page which represents the primary page of a form ''' 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 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 ''' ''' Add a new DetailPage or a new PrimaryPage ''' 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 ''' ''' Add a list of new DetailPages or new PrimaryPages ''' Public Sub AddRange(ParamArray Pages As DetailPage()) For Each oPage In Pages Add(oPage) Next End Sub ''' ''' Get the DetailPage which uses the given `TabPage` ''' 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 ''' ''' Saves the pending changes to the binding source ''' ''' True, if changes were made, otherwise False 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