Radical Documentation
View on GitHub
Primary version
Primary version
  • Home
  • Presentation
    • AbstractViewModel
    • Conventions
      • Bootstrap Conventions
      • Runtime Conventions
      • Conventions override
    • Commands and DelegateCommand
    • IViewResolver
      • Default view behaviors
      • view life cycle events
        • Callback expectations
        • notify messages
    • Message broker MVVM built-in messages
    • Application boot process
      • Application configuration
      • Application shutdown
      • Singleton applications
    • AbstractMementoViewModel
      • Simple ViewModel graphs
      • Collections and complex ViewModel graphs
    • Validation and Validation Services
    • Resources
      • Services as resources
      • ViewModels as resources
  • UI Composition
    • UI Composition
      • Region content lifecycle
      • TabControl region
      • Create a custom region
  • Concepts
    • Inversion of Control
      • Third party DI containers
    • Entities
      • Property System
    • Messaging and Message Broker
      • POCO messages
      • Standalone message handlers
    • Observers
      • PropertyObserver
      • MementoObserver
      • BrokerObserver
  • Memento
    • Change Tracking Service
      • MementoEntity and MementoEntityCollection
      • Handling change tracking:
        • Simple model
        • Collections
        • Complex objects graph
      • Atomic operations
      • Change Tracking Service API
      • Property Metadata for the ChangeTrackingService
      • Handling collection sync
      • Property State
  • Behaviors
    • DataGrid Behaviors
    • Password
    • Generic routed event handler to command behavior
    • Overlay adorner
      • Busy status manager
    • TextBox behaviors:
      • Command
      • Auto select
      • DisableUndoManager (.Net 3.5 only)
  • Markup Extensions
    • Editor binding
    • Auto Command binding
  • How to
    • Get the view of a given view model
    • Bi-directional communication between different windows/views
    • Handle the busy status during async/long running operations
    • Implement a customer improvement program
    • Manage focus
    • Create a splash screen
    • Access view model after view is closed
    • Intercept ViewModels before they are used
  • Upgrade guides
    • Radical Presentation 1.x to Radical 2.x for .NET Core
    • Radical 2.0.0 to Radical 2.1.0
Powered by GitBook
On this page
  1. How to

Implement a customer improvement program

From the perspective of an application producer it is really important to know what our end users do with the application they use:

  • we plan a feature;

  • we invest money in building a feature;

  • we deploy a feature;

we know nothing about how the user utilizes the feature we invested on, we do not even know if the user utilizes it at all.

AnalyticsServices.UserActionTrackingHandler = evt =>
{
    //every user action will be dispatched here asynchronously    
};

AnalyticsServices.IsEnabled = true;

Writing the above code at the application startup enables the Radical AnalyticsServices, what happens is that all the code that in some way invokes a DelegateCommand, in a WPF MVVM based application, will be tracked and we have the opportunity to “save” what the user is doing in order to analyze it later.

What the UserActionTrackingHandler receives is an AnalyticsEvent with the following shape:

public class AnalyticsEvent
{
    public AnalyticsEvent()
    {
        this.ExecutedOn = DateTimeOffset.Now;
        this.Identity = Thread.CurrentPrincipal.Identity;
    }

    public DateTimeOffset ExecutedOn { get; set; }

    public String Name { get; set; }

    public Object Data { get; set; }

    public IIdentity Identity { get; set; }
}

If we need we can define our own events inheriting from the AnalyticsEvent class and in order to plugin our events we only need to declare a dependency on the IAnalyticsServices service:

public interface IAnalyticsServices
{
    Boolean IsEnabled { get; set; }
    void TrackUserActionAsync( Analytics.AnalyticsEvent action );
}

And each time we call TrackUserActionAsync the UserActionTrackingHandler will be invoked.

PreviousHandle the busy status during async/long running operationsNextManage focus

Last updated 3 years ago