Group: StrataFrame Users
Posts: 223,
Visits: 893
|
Is anyone using SF BO/Business Binding Source with DevExpress Scheduler/Calendar control? I have successfully used it with the standard .NET table adapter/dataset. I am not able to get it to work with the SF BO/BBS. I have looked at the SF Custom Business Binding Source example in Strataflix. The Stratafix example is showing it used with reports. Can anyone tell me if this SF custom BBS will work with the DevX scheduler/calendar control? If so, do you have an example on how you did it or any tips/tricks on getting it to work right? Thanks, Jeff
|
Group: Forum Members
Posts: 386,
Visits: 2.1K
|
Hi Jeff,
We have used a BBS as the Appointments data source in a Scheduler Control. That part worked fine but I seem to remember we had a deal of problems just coming to grips with the concepts involved and, as I remember, either the DX documentation wasn't real good or I wasn't real smart in undertstanding it.
We did get it all working and it works well for us - just simple system housekeeping that we could have probably achieved easier by using the Windows Task Scheduler but we wanted more flexibilty and extensibility for the future.
FWIW following is all the code in form that contains the Scheduler Control. There may be bits in it that are useful to you but I certainly wouldn't say what we have done is 'best practice'. I know we made heavy going of it at times.
Cheers, Peter
Option Explicit On
Option Strict On
Imports System.Data.SqlClient
Imports DevExpress.XtraGrid
Imports DevExpress.XtraPrinting
Imports clsFU = UtilForms.clsFormUtility
Imports clsFP = UtilForms.clsFormPrint
Imports clsHE = UtilHelp.clsHelp
Imports clsLOC = UtilLocalisation.clsLocalise
Imports clsRTE = UtilRunTimeEnvironment.clsRunTimeEnv
Imports clsSSV = UtilSundry.clsServices
Imports clsLOG = UtilLogging.clsLogging
Imports MicroFour.StrataFrame.Messaging
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports DevExpress.XtraScheduler.UI
Imports DevExpress.XtraScheduler
Imports DevExpress.XtraScheduler.Native
'
Public Class frmSCH
#Region " Initialisation during form loading "
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' TMS Standard form configuration
clsFU.LocaliseAllControls(Me)
clsFU.ConfigureEmbeddedNavigator(Me, Me.Images16x16)
clsFU.SetLookAndFeel(Me.DefaultLookAndFeel1)
clsFU.SetTheFormTechName(Me)
clsFU.SetSundryProperties(Me, Me.Images32x32, clsRTE.RightToLeft, clsRTE.StartXPosition, clsRTE.StartYPosition)
clsFU.LocaliseSFMessages(Me)
clsFU.SetGridNonStandardProperties(Me)
Me.GradientFormHeader1.DetailText = clsRTE.CMPTanneryName
AddHandler schedulerControl1.SelectedAppointments.CollectionChanged, AddressOf SelectedAppointments_CollectionChanged
AddHandler schedulerControl1.SelectedAppointments.CollectionChanging, AddressOf SelectedAppointments_CollectionChanging
' Handle the ParseString and ConvertToString events of the HumanReadableTimeSpanHelper.
AddHandler HumanReadableTimeSpanHelper.ParseString, AddressOf OnParse
AddHandler HumanReadableTimeSpanHelper.ConvertToString, AddressOf OnToString
schedulerControl1.OptionsCustomization.AllowAppointmentConflicts = AppointmentConflictsMode.Allowed
schedulerControl1.OptionsCustomization.AllowAppointmentCopy = UsedAppointmentType.None
schedulerControl1.OptionsCustomization.AllowAppointmentMultiSelect = False
schedulerControl1.OptionsView.FirstDayOfWeek = DevExpress.XtraScheduler.FirstDayOfWeek.Sunday
schedulerControl1.OptionsView.HideSelection = False
schedulerControl1.OptionsView.NavigationButtons.Visibility = NavigationButtonVisibility.Always
schedulerControl1.OptionsView.ShowOnlyResourceAppointments = False
schedulerControl1.OptionsView.ToolTipVisibility = ToolTipVisibility.Always
schedulerControl1.OptionsBehavior.RecurrentAppointmentDeleteAction = RecurrentAppointmentAction.Series
schedulerControl1.OptionsBehavior.RecurrentAppointmentEditAction = RecurrentAppointmentAction.Series
schedulerControl1.OptionsBehavior.RemindersFormDefaultAction = RemindersFormDefaultAction.SnoozeAll
schedulerControl1.OptionsBehavior.SelectOnRightClick = True
schedulerControl1.OptionsBehavior.ShowRemindersForm = True
schedulerControl1.GroupType = SchedulerGroupType.Date
' Get the current schedule details from the database and populate the schedule
' with a data table.
CType(Me.PrimaryBusinessObject, UtilBOBase.boTMSMaintBase).TMSStandardFill()
SchedulerStorage1.Resources.DataSource = Nothing
SchedulerStorage1.Appointments.DataSource = Nothing
schedulerControl1.BeginUpdate()
SchedulerStorage1.BeginUpdate()
SchedulerStorage1.Appointments.DataSource = Me.BoSCH1.CurrentDataTable
SchedulerStorage1.EndUpdate()
schedulerControl1.EndUpdate()
End Sub
#End Region
#Region " DevExpress customised recurrence form handling "
Public Class MyAppointmentForm
Inherits AppointmentForm
Public Sub New(ByVal control As SchedulerControl, ByVal apt As Appointment)
MyBase.New(control, apt)
End Sub
Public Sub New(ByVal control As SchedulerControl, ByVal apt As Appointment, ByVal openRecurrenceForm As Boolean)
MyBase.New(control, apt, openRecurrenceForm)
End Sub
Protected Overrides Function CreateAppointmentRecurrenceForm(ByVal patternCopy As Appointment, ByVal firstDayOfWeek As DevExpress.XtraScheduler.FirstDayOfWeek) As Form
Dim frm As TMSSystemTableMaint.WindowsApplication1.XtraForm1 = New TMSSystemTableMaint.WindowsApplication1.XtraForm1(patternCopy, firstDayOfWeek, Me.Controller)
frm.LookAndFeel.ParentLookAndFeel = Me.LookAndFeel
frm.ShowExceptionsRemoveMsgBox = Me.Controller.AreExceptionsPresent()
Return frm
End Function
End Class
Private Sub schedulerControl1_EditAppointmentFormShowing(ByVal sender As Object, ByVal e As AppointmentFormEventArgs) Handles schedulerControl1.EditAppointmentFormShowing
Dim frm As New MyAppointmentForm(TryCast(sender, SchedulerControl), e.Appointment, e.OpenRecurrenceForm)
' Standard setting for TMS. Always recurring, always has a reminder and can only
' maintain in the recurrence form
' This works fine when the form is opened but when returning to the form
' from the recurring form all our Enabled = False are set back to True.
CType(frm.Controls("chkReminder"), DevExpress.XtraEditors.CheckEdit).EditValue = True
CType(frm.Controls("chkAllDay"), DevExpress.XtraEditors.CheckEdit).EditValue = False
CType(frm.Controls("cbReminder"), DevExpress.XtraScheduler.UI.DurationEdit).EditValue = Parse("0")
frm.Controls("edtStartTime").Enabled = False
frm.Controls("edtStartDate").Enabled = False
frm.Controls("edtEndTime").Enabled = False
frm.Controls("edtEndDate").Enabled = False
frm.Controls("chkAllDay").Enabled = False
frm.Controls("chkReminder").Enabled = False
frm.Controls("cbReminder").Enabled = False
If Me.BoSCH1.IsDirty Then
' Save the dataset to the database if it has changed.
Me.BoSCH1.Save()
End If
'---------------------------------------------
e.DialogResult = frm.ShowDialog()
e.Handled = True
End Sub
#End Region
#Region " Time span parsing - standard DX code "
Private Function Parse(ByVal str As String) As TimeSpan
End Function
' Custom parsing of a string to a TimeSpan value.
Private Sub OnParse(ByVal sender As Object, ByVal e As TimeSpanStringConvertEventArgs)
Dim val As Double
Try
Dim number As String = e.StringValue.Substring(0, e.StringValue.IndexOf(" minutes"))
val = Convert.ToDouble(number)
Catch
val = 0
End Try
e.TimeSpanValue = TimeSpan.FromMinutes(val)
e.Handled = True
End Sub
' Custom conversion of a TimeSpan value to a string.
Private Sub OnToString(ByVal sender As Object, ByVal e As TimeSpanStringConvertEventArgs)
e.StringValue = "0 minutes" ' e.TimeSpanValue.TotalMinutes.ToString() + "0 minutes"
e.Handled = True
End Sub
#End Region
#Region " TMS code for handling custom fields and propergating changes to the database "
Private Sub SchedulerStorage1_AppointmentDeleting(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectCancelEventArgs) Handles SchedulerStorage1.AppointmentDeleting
' Delete the in the dataset
Me.UpdateCustomFieldsInBO(Me.BoSCH1.CurrentRowIndex, False, True)
InitCustomFieldsB4NewAndAfterDelete()
End Sub
Private Sub SchedulerStorage1_AppointmentInserting(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectCancelEventArgs) Handles SchedulerStorage1.AppointmentInserting
Me.schedulerControl1.Visible = False
Me.btnSaveTMSInfoNewSchedule.Visible = True
InitCustomFieldsB4NewAndAfterDelete()
End Sub
Private Sub InitCustomFieldsB4NewAndAfterDelete()
Me.luScheduleJobType.EditValue = 1
Me.luScheduleRunOn.EditValue = 1
Me.txtSCHDXSubject.Text = ""
Me.txtSCHJobFolder.Text = ""
Me.txtSCHJobName.Text = ""
Me.txtSCHJobParameters.Text = ""
Me.txtSCHJobFolder.Focus()
Me.Refresh()
End Sub
Private Sub SchedulerStorage1_AppointmentInserted(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsInserted
' Ensure the new Appointment has a valid GUID as its PK when it finally gets saved
' The new row is always at the end of the dataset.
' At this stage we haven't had a chance to enter our custom field values.
If BoSCH1.MoveLast Then
Me.UpdateCustomFieldsInBO(BoSCH1.CurrentRowIndex, True, False)
End If
End Sub
' Private Sub SelectedAppointments_CollectionChanged(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.CollectionChangedEventArgs(Of DevExpress.XtraScheduler.Appointment))
Private Sub SelectedAppointments_CollectionChanged(ByVal sender As Object, ByVal e As DevExpress.Utils.CollectionChangedEventArgs(Of Appointment))
' This code was used to show the custom field values on the main form.
' for the newly selected Appointment.
' Skip this if we are saving a new record
If Not Me.btnSaveTMSInfoNewSchedule.Visible Then
' Loop through all the selected appointments. Will only every be one becuause
' multi-select is turned off
For idx As Integer = 0 To schedulerControl1.SelectedAppointments.Count - 1
' This was needed because Custom Fields seem to 'disappear' at times. This
' may be my imagination
If Not schedulerControl1.SelectedAppointments(idx).CustomFields Is Nothing Then
' Set focus in the dataset to the appointment just selected.
If BoSCH1.SeekToPrimaryKey(schedulerControl1.SelectedAppointments(idx).CustomFields("SCHID")) Then
' Populate the custome text fields on the main form with the existing info from the dataset
If Not IsDBNull(Me.BoSCH1.SCHJobName) Then
Me.txtSCHJobName.Text = Me.BoSCH1.SCHJobName.ToString
End If
If Not IsDBNull(Me.BoSCH1.SCHJobParameters) Then
Me.txtSCHJobParameters.Text = Me.BoSCH1.SCHJobParameters.ToString
End If
If Not IsDBNull(Me.BoSCH1.SCHJobFolder) Then
Me.txtSCHJobFolder.Text = Me.BoSCH1.SCHJobFolder.ToString
End If
If Not IsDBNull(Me.BoSCH1.SCHDXSubject) Then
Me.txtSCHDXSubject.Text = Me.BoSCH1.SCHDXSubject.ToString
End If
If Not IsDBNull(Me.BoSCH1.SCHRunOn) Then
Me.luScheduleRunOn.EditValue = Me.BoSCH1.SCHRunOn
End If
If Not IsDBNull(Me.BoSCH1.SCHJobType) Then
Me.luScheduleJobType.EditValue = Me.BoSCH1.SCHJobType
End If
End If
End If
Next
End If
End Sub
' Private Sub SelectedAppointments_CollectionChanging(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.Native.CollectionChangingEventArgs(Of DevExpress.XtraScheduler.Appointment))
Private Sub SelectedAppointments_CollectionChanging(ByVal sender As Object, ByVal e As DevExpress.Utils.CollectionChangingEventArgs(Of Appointment))
' Loop through all the selected appointments. Will only every be one becuause
' multi-select is turned off. At this stage the selected Appointment is
' the one about to loose focus.
Dim UpdateNeeded As Boolean = False
For idx As Integer = 0 To schedulerControl1.SelectedAppointments.Count - 1
' This was needed because Custom Fields seem to disappear at times. This
' may be my imagination
If Not schedulerControl1.SelectedAppointments(idx).CustomFields Is Nothing Then
If BoSCH1.SeekToPrimaryKey(schedulerControl1.SelectedAppointments(idx).CustomFields("SCHID")) Then
' Only change the dataset if there has been a change to values
' in our custom fields.
If Me.BoSCH1.SCHJobName <> Me.txtSCHJobName.Text OrElse _
Me.BoSCH1.SCHJobParameters <> Me.txtSCHJobParameters.Text OrElse _
Me.BoSCH1.SCHJobFolder <> Me.txtSCHJobFolder.Text Then
UpdateNeeded = True
ElseIf Me.luScheduleRunOn.EditValue Is Nothing Then
UpdateNeeded = False
ElseIf Me.BoSCH1.SCHRunOn.Value <> CType(Me.luScheduleRunOn.EditValue, Integer) Then
UpdateNeeded = True
ElseIf Me.luScheduleJobType.EditValue Is Nothing Then
UpdateNeeded = False
ElseIf Me.BoSCH1.SCHJobType.Value <> CType(Me.luScheduleJobType.EditValue, Integer) Then
UpdateNeeded = True
End If
If UpdateNeeded Then
Me.UpdateCustomFieldsInBO(Me.BoSCH1.CurrentRowIndex, False, False)
End If
End If
End If
Next
End Sub
Private Sub btnSaveTMSInfo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSaveTMSInfoNewSchedule.Click
' Save the TMS specific info for a new record.
' New records are always at the end of the dataset.
If BoSCH1.MoveLast Then
Me.txtSCHDXSubject.Text = Me.BoSCH1.SCHDXSubject
Me.UpdateCustomFieldsInBO(Me.BoSCH1.CurrentRowIndex, False, False)
End If
' Back to normal maintenance
Me.txtSCHJobFolder.Focus()
Me.btnSaveTMSInfoNewSchedule.Visible = False
Me.schedulerControl1.Visible = True
Me.Refresh()
End Sub
Private Sub UpdateCustomFieldsInBO(ByVal RowIndex As Integer, ByVal CreatePKOnly As Boolean, ByVal DeleteOnly As Boolean)
' The MoveAbsolutes is needed because the code "boSCH1?? = txtSCH??" below actually
' sets the current row index in the BO to 0. No idea why.
' Updating the BO caused following events to fire. Cleary the appointements know
' when the underlying dataset changes. Anyway Removing and readding the handlers seemed
' fix that problem
RemoveHandler schedulerControl1.SelectedAppointments.CollectionChanging, AddressOf SelectedAppointments_CollectionChanging
RemoveHandler schedulerControl1.SelectedAppointments.CollectionChanged, AddressOf SelectedAppointments_CollectionChanged
If CreatePKOnly Then
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHID = Guid.NewGuid
ElseIf DeleteOnly Then
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.DeleteCurrentRow()
Else
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHJobFolder = Me.txtSCHJobFolder.Text
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHJobName = Me.txtSCHJobName.Text
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHJobParameters = Me.txtSCHJobParameters.Text
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHJobType = CType(Me.luScheduleJobType.EditValue, Integer)
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.SCHRunOn = CType(Me.luScheduleRunOn.EditValue, Integer)
End If
Me.BoSCH1.MoveAbsolute(RowIndex)
Me.BoSCH1.Save()
Me.BoSCH1.MoveAbsolute(RowIndex)
AddHandler schedulerControl1.SelectedAppointments.CollectionChanging, AddressOf SelectedAppointments_CollectionChanging
AddHandler schedulerControl1.SelectedAppointments.CollectionChanged, AddressOf SelectedAppointments_CollectionChanged
End Sub
#End Region
#Region " Help button processing "
Private Sub btnHelp_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnHelp.Click
clsHE.FormHelpClicked(Me.Name, False, clsRTE.UserName)
End Sub
#End Region
#Region " Standard Event Handling for Form using clsFormUtility "
Private Sub LogInfo(ByVal Message As String)
Dim LogMsg As New System.Text.StringBuilder
LogMsg.AppendFormat("{1} - {2} at {3}{0}{4}", _
Environment.NewLine, _
"HouseKeepingScheduleMaint", _
Now.ToLongDateString, _
Now.ToShortTimeString, _
Message)
clsLOG.LogTMSEvent(LogMsg.ToString, UtilLogging.clsLogging.TMSLogType.TMSServices)
End Sub
'---------------------------------------------------------------
' Form Closing and Closed
' Note: the specific nature of Form Load precludes its inclusion here.
Private Sub ThisForm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) _
Handles Me.FormClosed
Try
clsFU.HandleFormClosed(CType(sender, System.Windows.Forms.Form), e)
Catch ex As Exception
End Try
End Sub
Private Sub ThisForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
Try
If Me.BoSCH1.IsDirty Then
BoSCH1.Save()
End If
LogInfo("Restarting TMSHousekeepingService in frmSCH")
clsSSV.RestartService("TMSHousekeepingService")
LogInfo("Restarted TMSHousekeepingService in frmSCH")
clsFU.HandleFormClosing(CType(sender, System.Windows.Forms.Form), e)
Catch ex As Exception
End Try
End Sub
#End Region
End Class
|
Group: StrataFrame Users
Posts: 223,
Visits: 893
|
Peter, Thanks so much for the info. I will take a close look at what you are doing and try to implement it. It is good to know someone has gotten this to work with SF BBS. Just to be clear about how your form is setup. You have the scheduler storage and control objects, SF BO and SF BBS dropped on the form. You have mapped the scheduler control fields to the BO fields. Then you are managing the updates to the BO within the scheduler storage event handlers. Am I correct on this? Jeff
|
Group: Forum Members
Posts: 386,
Visits: 2.1K
|
Hi Jeff,
That's right. It was understanding the correct DX events to use was very problematic.
Cheers, Peter
|
Group: Forum Members
Posts: 14,
Visits: 102
|
how to use business objects in xtra sheduling
I'm trying to appointments with Business Binding Source with DevExpress Scheduler / Calendar control
conssegui but I'm not someone help me?
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
It has been a while since I have looked at the DevExpress scheduler, but in this case, I sat down with Jeff when he came to class and showed him how to populate the business object and then manually populate the appointments on the scheduler. I recall the direct binding to this control (outside of StrataFrame included) being a bit tricky with some strange side-effects.
|
Group: StrataFrame MVPs
Posts: 1.9K,
Visits: 21K
|
Hi Jéssica. Also, have a look at this post from Paul Chase and it might help you: http://forum.strataframe.net/FindPost8050.aspxAbraços.
|