Reputation: 71
I am trying to use messaging center instead of Messenger in xamarin forms I have no idea about messaging center I tried Bellow code to subscribe and Send Message in xamarin forms
MessagingCenter.Send(this, "TodoTable", "Todo");
But I have not Idea from where I can subscribe to this message I tried bellow code :
MessagingCenter.Subscribe<TodoClass>(this, Todo, async (sender, arg) =>
{
await RefreshCommand.ExecuteAsync();
});
This is giving me error Any Help will appreciated :)
Upvotes: 4
Views: 16615
Reputation: 31
Send Method
MessagingCenter.Send<Application>(Application.Current,"RefreshDocs");
Subscribe Method
MessagingCenter.Subscribe<Application>(Application.Current , "RefreshDocs" , (sender) =>
{
});
Upvotes: 0
Reputation: 3358
To improve the answer by @user2825546, if you wish to subscribe to only messages from your view-models, you need to specify the base class type when sending the message:
MessagingCenter.Subscribe<BaseViewModel, string>(this, "ShowError", (view, message) => { });
public class StartupViewModel : BaseViewModel
{
//Like this...
MessagingCenter.Send<BaseViewModel, string>(this, "ShowError", "Message");
//Or...
MessagingCenter.Send((BaseViewModel)this, "ShowError", "Message");
}
When testing, I tried to send the message as StartupViewModel
, but the listener was not receiving the messages. I guessed that it would, since the class derives from the BaseViewModel
.
Upvotes: 0
Reputation: 154
It is a quirk of XF messaging centre that (it seems) you need to know who will be sending the message, and potentially who will be receiving it.
However it can be object. The signature of subscribe is:
void MessagingCenter.Subscribe<TSender>(object subscriber, string message, Action<TSender> callback, TSender sender = null)
The trick is to subscribe thus:
MessagingCenter.Subscribe<object>(this, "messageName", Action<object> callback)
This says object or anything derived from object can be a sender, ie, everything.
However if you want to only subscribe to messages sent by a particular instance of a type:
MessagingCenter.Subscribe<MyClass>(this, "messageName", Action<MyClass> callback)
The use of the full signature is a bit suspect. Basically it is saying only if sent from the source object are subscribers who used that source object when subscribing.
MessagingCenter.Subscribe<object, string>(this, "Hi",
(sender, arg) =>
{
DisplayAlert("Message Received", "arg=" + arg, "OK");
},
BindingContext);
if you use the following to send the message it wont be received by the subscriber just above:
MessagingCenter.Send<object, string>(this, "Hi", "John");
But the following will be received
MessagingCenter.Send<object, string>(BindingContext, "Hi", "John");
Though why would you want to send a message to yourself. (Assuming the subscribe and send were in the same page in this case).
However if there were multiple pages with the exact same binding context the message will be sent to all such subscribers. Eg, pages bound to the same view model.
Upvotes: 5
Reputation: 305
The goal of MVVM is to abstract away your Views from your Business Logic. This ensures great code reuse, testability, and is pretty awesome. Many MVVM Frameworks offer tools to enhance this such as data binding and dependency services to make our lives easier. These are built into Xamarin.Forms, which is awesome, but one feature less talked about is the Messaging Center. It’s entire goal is to enable ViewModels or other components to communicate with each other without having to know anything about each other besides a simple Message contract.
So for instance, let’s say you are in a master/detail setup where your MasterViewModel has a list of items and your DetailViewModel allows you to create a new item, update an item, or delete an item. When your user is on the detail page and triggers an event you need to somehow message back to your MasterViewModel that has a list of Items so the UI can react on the Master page when we navigate back.
So let’s say our MasterViewModel subscribes to “Update” and “AddNew” message events. It will then update it’s observable collection based on when it receives messages. Our DetailViewModel would then send a message in our SaveCommand to notify anyone that is subscribed to these specific messages:
public ObservableCollection<TripExpense> Expenses { get; set; }
public ExpensesViewModel()
{
Expenses = new ObservableCollection<TripExpense>();
//Subscibe to insert expenses
MessagingCenter.Subscribe<TripExpense>(this, "AddNew", (expense) =>
{
Expenses.Add(expense);
});
//subscribe to update expenxes
MessagingCenter.Subscribe<TripExpense>(this, "Update", (expense) =>
{
ExecuteUpdateExpense(expense);
});
}
private async Task ExecuteSaveCommand()
{
if (IsBusy)
return;
IsBusy = true;
//Send a message to insert/update the expense to all subscribers
if(isNew)
{
MessagingCenter.Send(expense, "AddNew");
}
else
{
MessagingCenter.Send(expense, "Update");
}
IsBusy = false;
navigation.PopAsync();
}
There you have it, messaging made easy! Don’t forget to unsubscribe if you no longer wish to receive notifications.
Upvotes: -3