I have created a small "ExtendedAppointmentInfo" class to store some additional appoinment info.
<Serializable()> _Public Class ExtendedAppointmentInfo Private _PhoneNumber As String = Nothing
Public Property PhoneNumber() As String Get Return Me._PhoneNumber End Get Set(ByVal value As String) Me._PhoneNumber = value End Set End Property
End Class
I have my CalendarInfo bound to a Dataset (manually created in code at the moment - will eventually move it to a database). The AllPropertiesDataMember is a DataColumn called "AllProperties" and it has a data type of Byte()
Private Sub SaveAppointments(ByVal Appt as Appointment)
Dim info As ExtendedAppointmentInfo = Nothing info = TryCast(Me.appointment.Tag, ExtendedAppointmentInfo) info.PhoneNumber = "12345678" Appt.Tag = Info
End Sub
This All Works and Appointments.TAG property DOES appear to contain my "ExtendedAppointmentInfo" class. But I am having major problems trying to retrieve the data back.
For Instance. my data table was Declared "WITHEVENTS"
Private Sub AppointmentsTable_RowChanged(ByVal sender As Object, ByVal e As System.Data.DataRowChangeEventArgs) Handles AppointmentsTable.RowChanged If e.Action = DataRowAction.Add Then If Not IsNothing(e.Row("AllProperties")) And e.Row("AllProperties") IsNot System.DBNull.Value Then Dim Appt As Appointment = Appointment.FromBytes(e.Row("AllProperties")) Dim ExtendedInfo As ExtendedAppointmentInfo = DirectCast(Appt.Tag, ExtendedAppointmentInfo) MessageBox.Show(ExtendedInfo.PhoneHome) End If End If End Sub
The Problem is that When I try to retrieve the AllProperties column value it ALWAYS = System.DbNull.Value
Please help. I need to be able to cast the "All Properties" column back into an appointment object, then cast the appointment.tag back into an ExtendedAppointmentInfo Class.
I should probably mention my ultimate goal which is:
I am having trouble getting the AllProperties Column to populate correctly... everytime i convert the Appointment using
Dim Appt as Appointment = Appointment.FromBytes(_dataRoww("AllProperties"))
When I try to access the .TAG info using:
Dim MyClassInstance as MyClass = DirectCast(Appt.Tag,MyClass)
It is ALWAYS Null :(
At which point/which event should I capture the information in the Appt.Tag custom class and write it directly to my database? AfterAppointmentAdded? DataTable_RowChanged?
I hope i have made a little more sense
My Actual ExtendedAppointmentInfo Class contained a property of a TypeOf Custom class which was not marked as <Serializable()> _
Hence the problem when I added this class to the Appointment.Tag the WinSchedule controls could not serialize this data. It was subsequently wiping out the "AllProperties" info and the result would be NULL
CheersAaron
I am running into a similar issue with mine.
I have been trying to save off the data to their own columns so that i am able to Query the data in SQL rather than having to load all the appointments up and use the frombytes command.
Have you solved you issues? Do you leave all your extra data that you have collected in the "AllProperties" field?
Also i have another issue of when opening a existing appointment, when it first loads and i call
Dim info As ExtendedAppointmentInfo = DirectCast(e.Appointment.Tag, ExtendedAppointmentInfo)
info is always null the first time i open the dialog at least one, without saving back to the databse.....if that makes sense :)
It is like it is not loading the ExtendedAppointmentInfo correctly. However the info is being storred in the "AllProperties" field as the appointments are the correct colour on the UltraDayView
I have the same requirement.... I store LOTS of additional fields into a custom class which is stored into the Appointment.Tag object, subsequently that information is saved into the database into the "AllProperties" field as a binary representation of the Appointment object (including the .Tag)
My problem was that I also need to make some of this data "queryable" in a normal SQL query. The solution is to basically "double" store this information.... Once in the Custom class which is serialized and put in the AllProperties Field and secondly to split it out.
The Underlying "datarow" is accessible via the Appointment.BindingListObject... I cast an object into it and populate the "extracted" fields individually.
In my custom "SaveAppointment" Routine I do the following (note my code sample is not "complete" but it shows the crux of what I am doing:
If Not Me.isExistingAppointment Then ' Add the appointment Me.appointment.Owner = Me.appointmentowner Dim apptAsClone As ICloneable = DirectCast(Me.appointment, ICloneable) Dim newappt As Appointment = DirectCast(apptAsClone.Clone, Appointment) newappt.Owner = Me.appointmentowner Dim addedAppointment As Appointment = Me.calendarInfo.Appointments.Add(newappt) Dim rw As DataRowView = DirectCast(addedAppointment.BindingListObject, DataRowView) 'DirectCast(addedAppointment.BindingListObject, DataRowView) rw.BeginEdit() rw("Specialist") = exinfo.Specialist rw("Technician") = exinfo.Technician rw("Title") = exinfo.Title rw("Phone") = exinfo.PhoneHome rw("Mobile") = exinfo.PhoneMobile rw("WhoIsMakingAppointment") = exinfo.WhoIsMakingAppointment rw("Referrer") = exinfo.Referrer rw("Surname") = exinfo.Surname rw("FirstName") = exinfo.GivenNames rw("AppointmentRequest") = addedAppointment.Location rw("PatientType") = exinfo.PatientType rw("PaymentMethod") = exinfo.PaymentMethod rw("FeeEstimate") = exinfo.FeeEstimate 'rw("SMSGuid") = exinfo.SMSGUID rw.EndEdit() Else Dim rw As DataRowView = DirectCast(Me.appointment.BindingListObject, DataRowView) rw.BeginEdit() rw("Specialist") = exinfo.Specialist rw("Technician") = exinfo.Technician rw("Title") = exinfo.Title rw("Phone") = exinfo.PhoneHome rw("Mobile") = exinfo.PhoneMobile rw("WhoIsMakingAppointment") = exinfo.WhoIsMakingAppointment rw("Referrer") = exinfo.Referrer rw("FirstName") = exinfo.GivenNames rw("Surname") = exinfo.Surname rw("AppointmentRequest") = Me.appointment.Location rw("PatientType") = exinfo.PatientType rw("PaymentMethod") = exinfo.PaymentMethod rw("FeeEstimate") = exinfo.FeeEstimate rw.EndEdit() End If
Hope this helps
RegardsAaron
you don't need to do anything to "load it back into the tag property"
As long as you have the AllProperties bound to a datasource then the appointment will be loaded from the AllProperties data. The data in the AllProperties is the ENTIRE Appointment Object INCLUDING the Tag.
I'm not sure I understand your question....
If you programatically create an appointment object and set the TAG object to a serializable type or class... then that is all you have to do.
To read that information again from the tag object you need to CAST into the original object. eg:
Dim eacls as ExtendedAppointmentClass = TryCast (Appointment.Tag, ExtendedAppointmentClass)If eacls IsNot Nothing Then Dim strMiddleName as String = eacsl.MiddleNameEnd If
Perhaps you can ellaborate on your problem
Hi Aaron,
Thanks so much for your help with this. I do how ever have another question.....i seem to be getting pretty confused with all of this.
I now have my extra information saving back into the allproperties area, but how do you load that infomation into your .tag on the inital open.
(Even following the sample they have "AppointmentDialog2007 VB" it uses a similar method and does not load the additional information into the appointment.tag until it has been opened the 2nd time)