This is a migrated thread and some comments may be shown as answers.

Appoint Changed Event in VB.NET

11 Answers 232 Views
Scheduler and Reminder
This is a migrated thread and some comments may be shown as answers.
Timothy
Top achievements
Rank 1
Timothy asked on 19 Jan 2013, 01:42 AM

(Sorry, the title should read "Appointment Changed Event in VB.NET" but I don't seem to be able to change it.)

The RadScheduler has several events:

  • AppointmentAdded
  • AppointmentDeleted
  • AppointmentEditDialogShowing

However, I don't see an AppointmentChanged event or AppointmentEditDialogShown event (or something to let me know that the edit dialog has been closed and I can persist the changes to the database).

Is this by design?

I found in another thread a mention of the RadScheduler.Appoinments.CollectionChanged event but in order to use it I have to use an AddHandler statement, something I'm not accustomed to in VB.

It just seems that an AppointmentChanged event would be an obvious event to implement.

11 Answers, 1 is accepted

Sort by
0
Timothy
Top achievements
Rank 1
answered on 19 Jan 2013, 02:25 AM
Also, I just tried to use the RadScheduler.Appointments.CollectionChanged event to persist my changes to the database and I get the following error: "There is already an open DataReader associated with this Command which must be closed first."

The code works fine if I call the code from a Save button as in your online documentation.
Here's the relavent code:
 
' Called from the form load event.
AddHandler rsMain.Appointments.CollectionChanged, AddressOf AppointmentChanged
 
    Private Sub AppointmentChanged(sender As Object, e As Telerik.WinControls.Data.NotifyCollectionChangedEventArgs)
        Me.CS_ScheduleInfoTableAdapter.Adapter.AcceptChangesDuringUpdate = False
        CS_ScheduleInfoTableAdapter.Update(Me.BillingDataSet.CS_ScheduleInfo)
        Me.BillingDataSet.AcceptChanges()
    End Sub

I'd rather not have the user be forced to click on a save button.

I saw a suggestion to use the ApplySettingsToEvent event from the custom editor dialog (which I've already implemented to handle custom fields) but I don't know how to persist the data from there and I didn't see how to do it in the online documentation. The data adapter I've been using is on the main form so is unavailable in the custom editor dialog. Do I need to create a new adapter on this form?

I'd really rather perform all the updates from the main form. It just seems like a lot of trouble to go through to persist the data as it is changed when the code to persist using a button is so simple.

Thanks.
0
Timothy
Top achievements
Rank 1
answered on 19 Jan 2013, 03:18 AM
I have a workaround in place.

I subscribe to the RadScheduler.Appointments.CollectionChanged event and start a timer. In the Tick event code of the timer I persist the appointments to the database using the table adapter. By the time the Tick event is fired the DataReader has been closed and I'm allowed to save.

Kind of a hack so if you have a better idea I'd love to hear it.
0
Ivan Todorov
Telerik team
answered on 23 Jan 2013, 09:03 AM
Hello Timothy,

Thank you for writing.

The proper way to listen about appointment changes is handling the CollectionChanged event. Also, using a timer is not recommended because it runs asynchronously and this might lead to unexpected behavior. The issue with "There is already an open DataReader" comes from the fact that the Update itself causes the CollectionChanged event to fire. You can protect this by using a flag to indicate that you are doing an update:
AddHandler rsMain.Appointments.CollectionChanged, AddressOf AppointmentChanged
Private updating as Boolean = False
 
    Private Sub AppointmentChanged(sender As Object, e As Telerik.WinControls.Data.NotifyCollectionChangedEventArgs)
        If updating Then
            Return
        End If
        Me.updating = True
        Me.CS_ScheduleInfoTableAdapter.Adapter.AcceptChangesDuringUpdate = False
        CS_ScheduleInfoTableAdapter.Update(Me.BillingDataSet.CS_ScheduleInfo)
        Me.BillingDataSet.AcceptChanges()
        Me.updating = False
    End Sub

As to calling an update from the ApplySettingsToEvent override, you can expose a public Update method of your main form, then pass a reference to the main from in the constructor of your custom edit dialog, then just call that Update method from the ApplySettingsToEvent method. This way you will have your update logic in the main form and just call it from the dialog.

I hope you find this useful. If you have any other questions, do not hesitate to ask.

Kind regards,
Ivan Todorov
the Telerik team
Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
0
Timothy
Top achievements
Rank 1
answered on 23 Jan 2013, 06:56 PM
I tried both of your workarounds (I consider them workarounds because they are clunky and counter-intuitive, at least for a VB.NET WinForms programmer.)

Using the "updating" flag does prevent the error message but it also seems to be preventing an actual update. Adds and Deletes work fine.

The risk with the timer workaround is minimal since it's only enabled for one second and is disabled as soon as the tick event occurs (before anything is saved). Besides that, it's the only thing that has worked for updates so far.

As far as passing the form doing the calling into the form that is being called... I don't know, that just seems recursive and awkward. I tried it though. I could probably get it to work if I wasn't using table adapters but I was trying to keep in sync with the rest of the code. I put the code below in an UpdateEvent public sub and called it from the ApplySettingsToEvent override as you suggested. Was this not what you had in mind? It doesn't update anything.
 
Me.CS_ScheduleInfoTableAdapter.Adapter.AcceptChangesDuringUpdate = False
CS_ScheduleInfoTableAdapter.Update(Me.BillingDataSet.CS_ScheduleInfo)
Me.BillingDataSet.AcceptChanges()
0
Ivan Todorov
Telerik team
answered on 24 Jan 2013, 12:24 PM
Hi Timothy,

I am attaching a small sample project which demonstrates my previous suggestions. Note that using the "updating" flag works correctly in the sample. As to the ApplySettingsToEvent override, this is not applicable in all cases as this method is called before the newly created appointment is added to the collection. Using this method for performing updates can be useful only if you are managing your database directly with queries.

As to your solution with the timer, you can use it if you consider it safe. In fact, issues with it are extremely unlikely to occur although they are potentially possible due to the asynchronous execution when using timers. For example, you can trigger an update during another internal update in RadScheduler.

I hope I was able to help. If you have any other questions, do not hesitate to write back.

Regards,
Ivan Todorov
the Telerik team
Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
0
Timothy
Top achievements
Rank 1
answered on 24 Jan 2013, 07:40 PM

The project will not compile. See attached image and snippet from vbproj file. Also, I am using VS 2010, not VS 2012.

I will correct the references and try to run the code. However, it looks pretty much like what I had.

<ItemGroup>
  <ProjectReference Include="..\..\RadControls\RadControlsUI.Design\Telerik.WinControls.UI.Design.csproj">
    <Project>{47E6BA89-8E32-4BE0-BACA-E1D1A650766D}</Project>
    <Name>Telerik.WinControls.UI.Design</Name>
  </ProjectReference>
  <ProjectReference Include="..\..\RadControls\RadScheduler\Telerik.WinControls.Scheduler.csproj">
    <Project>{72DCC7B6-6747-4DEE-B810-B5B02859E1D1}</Project>
    <Name>Telerik.WinControls.Scheduler</Name>
  </ProjectReference>
</ItemGroup>
0
Ivan Todorov
Telerik team
answered on 25 Jan 2013, 07:54 AM
Hello Timothy,

Yes, usually when we send sample project, the client needs to correct the references to the Telerik dlls. This is needed because in some cases we use a developer environment to create and test the samples and in this case we use project references. All you need to do on your end is delete the missing references and add them again via the "Add Reference..." dialog of Visual Studio.

Let me know if you have further questions.

All the best,
Ivan Todorov
the Telerik team
Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
0
Timothy
Top achievements
Rank 1
answered on 25 Jan 2013, 05:54 PM

In my opinion, if you supply a sample product to your client you should try to make sure it works. At least don't reference a project you know is not on your clients machine.

Still doesn't work after I fixed your incorrect reference:

System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=An error occurred creating the form. See Exception.InnerException for details.  The error is: Unable to cast object of type 'Telerik.WinControls.UI.SchedulerBindingDataSource' to type 'System.ComponentModel.ISupportInitialize'.
  Source=WindowsApplication11
  StackTrace:
       at WindowsApplication11.My.MyProject.MyForms.Create__Instance__[T](T Instance) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 190
       at WindowsApplication11.My.MyProject.MyForms.get_Form1()
       at WindowsApplication11.My.MyApplication.OnCreateMainForm() in C:\Users\Timmie\Documents\Visual Studio 2010\Projects\SchedExample\My Project\Application.Designer.vb:line 35
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at WindowsApplication11.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.InvalidCastException
       HResult=-2147467262
       Message=Unable to cast object of type 'Telerik.WinControls.UI.SchedulerBindingDataSource' to type 'System.ComponentModel.ISupportInitialize'.
       Source=WindowsApplication11
       StackTrace:
            at WindowsApplication11.Form1.InitializeComponent() in C:\Users\Timmie\Documents\Visual Studio 2010\Projects\SchedExample\Form1.Designer.vb:line 36
            at WindowsApplication11.Form1..ctor() in C:\Users\Timmie\Documents\Visual Studio 2010\Projects\SchedExample\Form1.vb:line 5
       InnerException:
0
Ivan Todorov
Telerik team
answered on 28 Jan 2013, 03:08 PM
Hello Timothy,

These lines which cast schedulerBindingDataSource1 to ISupportInitialize were incorrectly serialized in the designer file on my end. You can just try to remove them or you can try running the modified project attached to this message.

If you still need assistance, please let me know.

Regards,
Ivan Todorov
the Telerik team
Q3'12 SP1 of RadControls for WinForms is out now. See what's new.
0
Scott
Top achievements
Rank 1
answered on 09 Jan 2017, 07:36 PM

Hi Ivan-

Will post a C# version of how to create the Collection Changed event handler?
Thank you.

-Scott

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 10 Jan 2017, 09:10 AM
Hello Scott,

Thank you for writing.  

Here is the C# code snippet of the Appointments.CollectionChanged event:
private bool updating = false;
this.radScheduler1.Appointments.CollectionChanged += AppointmentChanged;


private void AppointmentChanged(object sender, Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e)
{
    if (updating) {
        return;
    }
    this.updating = true;
    this.CS_ScheduleInfoTableAdapter.Adapter.AcceptChangesDuringUpdate = false;
    CS_ScheduleInfoTableAdapter.Update(this.BillingDataSet.CS_ScheduleInfo);
    this.BillingDataSet.AcceptChanges();
    this.updating = false;
}

I would like to note that in the latest version of the suite when a change in an appointment's property occurs, the AppointmentChanged event is fired. The AppointmentChangedEventArgs gives you access to the exact Appointment and the PropertyName that has been modified.

I hope this information helps. Should you have further questions I would be glad to help.

Regards,
Dess
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Scheduler and Reminder
Asked by
Timothy
Top achievements
Rank 1
Answers by
Timothy
Top achievements
Rank 1
Ivan Todorov
Telerik team
Scott
Top achievements
Rank 1
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or