Search code examples
windows-phone-8mvvmcrossportable-class-library

Update UI thread from portable class library


I have an MVVM Cross application running on Windows Phone 8 which I recently ported across to using Portable Class Libraries.

The view models are within the portable class library and one of them exposes a property which enables and disables a PerformanceProgressBar from the Silverlight for WP toolkit through data binding.

When the user presses a button a RelayCommand kicks off a background process which sets the property to true which should enable the progress bar and does the background processing.

Before I ported it to a PCL I was able to invoke the change from the UI thread to ensure the progress bar got enabled, but the Dispatcher object isn't available in a PCL. How can I work around this?

Thanks

Dan


Solution

  • If you don't have access to the Dispatcher, you can just pass a delegate of the BeginInvoke method to your class:

    public class YourViewModel
    {
        public YourViewModel(Action<Action> beginInvoke)
        {
            this.BeginInvoke = beginInvoke;
        }
    
        protected Action<Action> BeginInvoke { get; private set; }
    
        private void SomeMethod()
        {
            this.BeginInvoke(() => DoSomething());
        }
    }
    

    Then to instanciate it (from a class that has access to the dispatcher):

    var dispatcherDelegate = action => Dispatcher.BeginInvoke(action);
    
    var viewModel = new YourViewModel(dispatcherDelegate);
    

    Or you can also create a wrapper around your dispatcher.

    First, define a IDispatcher interface in your portable class library:

    public interface IDispatcher
    {
        void BeginInvoke(Action action);
    }
    

    Then, in the project who has access to the dispatcher, implement the interface:

    public class DispatcherWrapper : IDispatcher
    {
        public DispatcherWrapper(Dispatcher dispatcher)
        {
            this.Dispatcher = dispatcher;
        }
    
        protected Dispatcher Dispatcher { get; private set; }
    
        public void BeginInvoke(Action action)
        {
            this.Dispatcher.BeginInvoke(action);
        }
    }
    

    Then you can just pass this object as a IDispatcher instance to your portable class library.