locked
Window Runtime Component and property changed RRS feed

  • Question

  • In INotifyPropertyChanged file

    public event PropertyChangedEventHandler PropertyChanged;

            private async void NotifyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    var ignored = await CoreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                        () => { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); });
                }
            }

     CoreDispatcher.RunAsync is a static method which does not accept  PropertyChanged(this, new PropertyChangedEventArgs(propertyName))

    How to resolve this problem.

    Best regards

    Agha Khan


    Agha Khan

    Thursday, December 26, 2013 8:16 AM

All replies

  • Typically you would call PropertyChanged directly, not asynchronously.

    That said, you should be able to call it through a dispatcher. I'm not sure what you mean by CoreDispatcher.RunAsync being a static method. RunAsync is not static and is called on a specific dispatcher object. Do you mean that you aren't finding the dispatcher correctly? Depending on the context your code is in you may need to cache the dispatcher reference or you may be able to get it from the current thread's corewindow.

    Thursday, December 26, 2013 2:57 PM
    Moderator
  • Dear Rob Caplan:
    Thank you for your kind email.

    If you are building Window Runtime Component you are NOT allowed to call directly. I tried to call it directly and got run time error that different thread is calling on UI thread. I am working with MVVM design pattern for a long time and never had a problem to call it directly but if you look the document (for building Window Runtime Component) you will see that you are not allowed to call with dispatcher either. The only way to call is  with CoreDispatcher.

    I just realized that CoreDispatcher has no constructors

    varcoreDispatcher = newCoreDispatcher();

    var ignored = await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () => { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); });

    How can I call CoreDispatcher? :-)

    Life is full of surprises

                   





    Agha Khan

    Thursday, December 26, 2013 7:42 PM
  • I'm not sure which documentation you refer to. It is not generally true that you cannot call event handlers directly from Windows Runtime Components. Doing so is demonstrated in several places in the docs. For example: Custom events and event accessors in Windows Runtime Components and Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript

    What you may be thinking of is that you need to raise an event from a background thread to be handled in JavaScript as discussed at Raising Events in Windows Runtime Components

    You cannot create a CoreDispatcher. You need to use the one already associated with the UI thread. Depending on where your code is running from you either can get that from the current thread's corewindow (if the thread has one) or you will need to save the dispatcher object from the thread you want to communicate with and then use that. The sample code in Raising Events in Windows Runtime Components gets the dispatcher from the current thread:

        var window = Windows.UI.Core.CoreWindow.GetForCurrentThread();
        m_dispatcher = window.Dispatcher;
    

    --Rob

    Thursday, December 26, 2013 9:46 PM
    Moderator
  • Dear Rob:

    Thank you for you email.

    As you suggested I used in this function 

     Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var propertyChangedEventArgs = new PropertyChangedEventArgs(propertyName);
                    }
                        );

    But I received this error message "VisualControls.CtrlCoreDispatcher': cannot derive from sealed type 'Windows.UI.Core.CoreDispatcher"

    VisualControls is a Runtime Component where I am displaying an image which can change dynamically change. The main window is using this control and if we are using your suggested code in main window it might work okay, but it didn't work in a DLL.

    Once again thanks for helping me.

    Best regards

    Agha


    Agha Khan

    Thursday, December 26, 2013 11:06 PM
  • What is VisualControls.CtrlCoreDispatcher? Are you trying to derive a class from CoreDispatcher? As the error says, you cannot do so. You need to use an existing instance of CoreDispatcher.

    The code you list is superficially correct, but depending on where it is called from you may not be able to depend on GetForCurrentThread returning a valid CoreWindow.

    --Rob

    Friday, December 27, 2013 12:08 AM
    Moderator
  • I didn't even know it where (CtrlCoreDispature) coming from.

    The good news is I think I have resolve the problem, because it is not crashing and also compiling.

    Here is the code.

    private CoreDispatcher _dispatcher = null;
            public event PropertyChangedEventHandler PropertyChanged;

            private async Task UIThreadAction(Action act)
            {
                await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => act.Invoke());
            }
            private async void PropertyChangedAsync(string property)
            {
                if (PropertyChanged != null)
                    await UIThreadAction(() => PropertyChanged(this, new PropertyChangedEventArgs(property)));
            }
          
            public FlipViewModel()
            {
                _dispatcher = Window.Current.Dispatcher;
            }

    Thanks for help Rob.


    Agha Khan

    Friday, December 27, 2013 12:34 AM