I am playing with your WINSCHEDULE DATABASE DEMO VB, trying to get it to integrate with my app. The main thing I need is to change the database structure of the demo to include a link to the rest of my data. Ideally for me this would be an integer ID, but I see that the Infragistic schema includes a string DataKey field that appears to be made for this purpose, and I can live with that.
I have modified the program and the database so it accepts the new DataKey field without causing an error. The issue is that when I send the DataKey to the appointment, it gets swallowed and doesn't come back or get written to the database.
In ultraCalendarInfo1_BeforeDisplayAppointmentDialog I am setting DataKey to a dummy value for testing:
e.Appointment.DataKey = "98765"
However, when I created a ultraCalendarInfo1_AfterCloseAppointmentDialog event and look at e.Appointment.DataKey it is empty.
I did some experimenting here and I am seeing the same behavior. Any DataKey you apply to the Appointment in the BeforeDisplayAppointmentDialog is lost for new appointments. It looks like when you show this dialog, the Appointment in the BeforeDisplayAppointmentDialog is used to populate the dialog initially. So if you were to change the Appointment Subject, it shows that new subjects in the dialog.
When you show this dialog for an existing appointment, the Appointment you get in the BeforeDisplayAppointmentDialog is the same instance the dialog modifies. But when you show the dialog for a new appointment, the Appointment on the event args is thrown away and a new Appointment object is created by the dialog. And that new appointment is only populate with the fields the user can see on the dialog. Since the DataKey is not visible, it's lost.
We could fix this, I suppose, but frankly, I don't think BeforeDisplayAppointmentDialog is the appropriate place to set the DataKey. For one thing, the user could cancel the dialog and then you will have populate a DataKey for nothing. In your case, since you are using it as some kind of link to external data, that's not a big deal. But the primary purpose of the DataKey is to allow you to store some kind of ID to link that appointment up to a record in your data source. So in that case, it would not make sense. Also, if the user show the dialog for an existing appointment, setting the DataKey in BeforeDisplayAppointmentDialog would also not be appropriate.
I think a much better solution for you would be to use the AfterAppointmentAdded. That event only fires for new appointments and only after the dialog is closed (and not cancelled). That would seem to solve all of the issues you are dealing with.
Thanks for the reply. I'm really struggling here trying to integrate these samples into my code. Two points: 1) I think Tag is thrown away too, not just DataKey (refer to Michael Peterson post above)2) In my app, I was planning on letting them make several appointments at a time. They will be looking at a grid of all the unscheduled assignments they have. They could then click on one or more and make appointments. I'm thinking that if we did it your way, in AfterAppointmentAdded, that if we had multiple instances it would be impossible to know which Tag to use. Not the end of the world I guess if we have to limit them to one appointment at a time.
It seems to me that you are simply creating a new appointment and passing it into the Dialog. That seems to indicate that you want the new appointment to be created whether the user Cancels the dialog or not. If that's the case, then it makes this very easy. Right now, you are creating the new appointment, but you are just creating it outside of the CalendarInfo. So maybe all you need to do is add it to the Appointments collection and THEN show the dialog. Since the appointment is an existing appointment in this case, and not a new one, the DataKey and other properties ARE maintained. So something like this:
Dim MyAppt As Appointment MyAppt = New Appointment(DateTime.Now, DateTime.Now.AddHours(1)) MyAppt.DataKey = DateTime.Now.Ticks Me.UltraCalendarInfo1.Appointments.Add(MyAppt) Me.UltraCalendarInfo1.DisplayAppointmentDialog(MyAppt)
Actually... when I do it this way, creating the Appointment and passing it in to Me.UltraCalendarInfo1.DisplayAppointmentDialog, the DataKey seems to be maintained, even if I DON'T add the appointment to the Appointments collection. So even if you comment out the second-to-last line of code above, it still works. I guess since I am passing an existing appointment object into the dialog, even though that Appointment is not in the CalendarInfo.Appointments collection, it treats it as an existing appointment and doesn't lose the extra data that is not in the UI.
So I think that should solve the issue for you either way.
Okay... I think I see the issue. So if the appointment doesn't already exist, you need to create a new one and show the dialog and you have the ID you need before showing the dialog, since you got it from the grid. So really all you need to do is store that information - and then apply it to the appointment that got created by the dialog. But you also need to know if the user cancelled the dialog and did NOT create the appointment. Or... do you want the appointment to get created even if the use cancels the dialog?
Ok, I will give you the 10,000 foot view, then ask a question at the end. I have an old stable application that would benefit from a scheduling function. I need to tie my existing database into the appointments, so I will use the tag field. There is an existing search / filter function in my app for the users case assignments. Those cases are displayed in an UltraWinGrid. Using the Tag, I retrieve the appointment date (if any) and display it in the grid. If they click on that I want to be able to edit that appointment. If there is no existing appointment, then I display the appointment dialog (using AppointmentDialog2007 VB.frmAppointmentDialog2007 as a template). I have the "add new" part working. I just need to know how to retrieve an existing appointment object using either the Tag or AppointmentID so I can pass it to the dialog. The ???? below is what I need. The code looks like this:
If mblnNew Then 'mblnNew indicates if this is an existing appointment Dim MyAppt As New Infragistics.Win.UltraWinSchedule.Appointment(dtSchedDate, dtSchedDate.AddHours(2)) Dim e As New Infragistics.Win.UltraWinSchedule.DisplayAppointmentDialogEventArgs(MyAppt, False) e.Appointment.Subject = "Case ID: " & CaseID.ToString & " Customer Name: " & mstrPassCaseName e.Appointment.Description = "Case ID: " & CaseID.ToString & " Customer Name: " & mstrPassCaseName e.Appointment.StartDateTime = dtSchedDate e.Appointment.EndDateTime = dtSchedDate.AddHours(2) e.Appointment.CalendarInfo = ultraCalendarInfo1 e.Appointment.Tag = mlngAuditID.ToString e.Appointment.OwnerKey = gstrSecuID Else 'TODO: Get existing data here and populate appointment Dim MyAppt As ???? <existing appointment retrieved by AppointmentID or Tag> Dim e As New Infragistics.Win.UltraWinSchedule.DisplayAppointmentDialogEventArgs(MyAppt, False) End If
ApptDlg = New AppointmentDialog2007 ApptDlg.Show(e.Appointment, Me.ultraCalendarInfo1, Me.ultraCalendarLook1, <some other stuff I pass>, mblnNew)
I'm not sure I understand what you mean by multiple appointments at once. The dialog only creates a single appointment. And the user can only create one at a time. Also... DataBinding has nothing to do with this, really. I did all my testing completely unbound. The dialog is the issue here. And yes, it will throw away anything that is not visible in the dialog's UI when you create a NEW Appointment. It's not really clear to me what you are trying to achieve here, or why you would know what the DataKey (or Tag) is before the appointment is created, but not after.
My current thinking is to just do all the data I/O manually, rather than use binding on the appointment itself. Not sure that's possible yet - keeping the monthly / weekly views bound to the data, then calling my own appointment dialog like the "AppointmentDialog2007 VB" demo. I would have to capture the appropriate events and do my own insert / update / deletes. Then rebind the source control (ultraMonthViewSingle for example) if necessary (will cross that bridge if I ever come to it).