简体   繁体   中英

How do I specify the sender in MessagingCenter.Send if the sender is a static class or an object in a static class?

I have a small project that contains a few pages that all reference a source-of-truth List in a static class. This static List is updated periodically using HTTPRequests. I am attempting to use Messaging Center to update the ObservableCollection in each of the page ViewModels whenever an update occurs but I'm having trouble figuring out how to make this work.

In the static class, I have tried to setup the MessagingCenter.Send() operation with the source-of-truth list being the sender, since I can set the class itself as the sender (keyword 'this' is not valid in a static property...). I also send the source-of-truth list as the argument. I'm not sure that this is valid, but I am not getting any errors so far and haven't been able to test its functionality by running it yet. Here is the relevant code from my static class:

using MyApp.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace MyApp.Services
{
    public static class MyListDataService
    {
        //The List
        private static ObservableCollection<ListItem> myList = new ObservableCollection<ListItem>();

        //Static Method for getting the list from another place
        public static ObservableCollection<ListItem> GetItems()
        {
            return myList;
        }

        //Method that updates the List
        public static async System.Threading.Tasks.Task<bool> RequestUpdatedListAsync()
        {

            // HTTPRequest code that updates local List...

            MessagingCenter.Send(myList, Constants._listUpdateContract, myList);

            return success;
        }
    }
}

The subscription is happening in the ViewModel of my ListPage like so:

using MyApp.Models;
using MyApp.Services;
using MyApp.Views;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using MvvmHelpers;

namespace MyApp.ViewModels
{
    public class ListPageViewModel
    {
        public ObservableRangeCollection<ListItem> MyList { get; private set; } = new ObservableRangeCollection<ListItem>(); 
        INavigation Navigation;

        public ListPageViewModel(INavigation MyListNavigation)
        {
            Navigation = MyListNavigation;

            MessagingCenter.Subscribe<MyListDataService.myList, ObservableCollection<ListItem>>(this, Constants._listUpdateContract, (s, a) =>
            {
                //populate list code
            });

        }
    }
}

I have tried making MyListDataService.myList public and referencing the MyListDataService.myList object as the specification of the receiving sender but when I do that I get an error: "The type name 'myList' does not exist in the type 'MyListDataService'. And even if it did work, I don't know if I should have that list be public anyway. What would be the correct way to do this? What should I specify as the sender in this case? Can this even work?

UPDATE: I've managed to get the code to compile by replacing

MessagingCenter.Send(myList, Constants._listUpdateContract, myList);

with

MessagingCenter.Send(Application.Current, Constants._listUpdateContract, myList);

and replacing

MessagingCenter.Subscribe<MyListDataService.myList, ObservableCollection<ListItem>>(this, Constants._listUpdateContract, (s, a) =>
            {
                //populate list code
            });

with

            MessagingCenter.Subscribe<App, ObservableCollection<ListItem>>(Application.Current, Constants._listUpdateContract, (s, a) =>
            {
                //populate list code
                System.Diagnostics.Debug.WriteLine(a.ToString());
            });

but the debug message is not being fired when a message is sent. Any insight into this new development?

Send and Subscribe need to use the same type parameters

MessagingCenter.Send<object,ObservableCollection<ListItem>>(Application.Current, Constants._listUpdateContract, myList);

MessagingCenter.Subscribe<object, ObservableCollection<ListItem>>(Application.Current, Constants._listUpdateContract, (s, a) =>
        {
            //populate list code
            System.Diagnostics.Debug.WriteLine(a.ToString());
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM