question

EduardoGomez-1870 avatar image
0 Votes"
EduardoGomez-1870 asked LeonLu-MSFT edited

Comunication betwen viewmodels

Hello

I have a list of notebooks, that are display on a listview (using syncfusion)

107841-notes.png

this is the VM to take care of that

   SelectedNoteBookCommand = new Command(async () => {
                 MessagingCenter.Send(this, "details", SelectedNotebook);
                 await Application.Current.MainPage.Navigation.PushAsync(new NotesPage());
                 SelectedNotebook = null;
             });
             GetNotebooksAsync();
         }
         private async void GetNotebooksAsync() {
             var notebooks = await Database.ReadAsync<Notebook>();
             if (notebooks != null) {
                 notebooks.Where(notebook => notebook.Id == App.UserId);
                 NotebooksCollection.Clear();
                 foreach (var item in notebooks) {
                     NotebooksCollection.Add(item);
                 }
    
             }
         }

so everything is perfect so far.

Now every notebook have several notes and each note has an id

What I am trying to do, is to use the Xamarin Messaging Center, to pass the entire Notebook, and get the Id



   NotesCollection = new ObservableCollection<Note>();
        
              
                 MessagingCenter.Subscribe<NotebooksVM, Notebook>(this, "details", async (obj, item) => {
                     Notebook newNotebook = item;
        
                     var notes = await Database.ReadAsync<Note>();
                     if (notes != null) {
                         var notebookNotes = notes.Where(n => n.NotebookId == newNotebook.Id);
                         NotesCollection.Clear();
                         foreach (var element in notebookNotes) {
                             NotesCollection.Add(element);
                         }
                     }
                 });

but when I try to display the notes, I don see anything, but I can see the Messaging center receiving the note (Not every time though).

This is my XAML to display that, but I don't understand

  <ContentPage.BindingContext>
         <vm:NotesVM/>
     </ContentPage.BindingContext>
     <ContentPage.Content>
         <StackLayout x:DataType="vm:NotesVM">
             <syncfusion:SfListView x:Name="NoteBookLV" 
                                       AutoFitMode="Height" 
                                       ItemsSource="{x:Binding NotesCollection}">
    
                 <syncfusion:SfListView.ItemTemplate>
                     <DataTemplate x:DataType="model:Note">
                         <Grid Padding="5" RowDefinitions="20,50">
                             <Label Text="{x:Binding CreatedAt, StringFormat='Created on: {0}'}"
                                    FontAttributes="Bold"
                                    BackgroundColor="Gray"/>
                             <StackLayout Grid.Row="1"
                                          Orientation="Horizontal">
                                 <Label Text="{x:Static fi:IconFonts.Note}"
                                        FontFamily="material" 
                                        VerticalTextAlignment="Center"
                                        FontSize="40"/>
                                 <Label Text="{x:Binding Title,StringFormat='Name: {0}'}"
                                        FontAttributes="Bold"
                                        VerticalTextAlignment="Center"/>
                             </StackLayout>
                         </Grid>
                     </DataTemplate>
                 </syncfusion:SfListView.ItemTemplate>
             </syncfusion:SfListView>
             <Button Text="{x:Static fi:IconFonts.Plus}" 
                     FontSize="30"
                     HorizontalOptions="EndAndExpand"
                     WidthRequest="50"
                     HeightRequest="50"
                     BorderWidth="2"
                     BorderColor="Gray"
                     CornerRadius="100"
                     Margin="30"
                     FontFamily="material"
                     VerticalOptions="End"/>
         </StackLayout>
     </ContentPage.Content>
 </ContentPage>










dotnet-xamarin
notes.png (110.6 KiB)
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

When you update view, please try to run your code in th UI thread like following code.

using Xamarin.Essentials;

MainThread.BeginInvokeOnMainThread(() =>
{
    // Code to run on the main thread
});



0 Votes 0 ·

It doesn't do anything

    NotesCollection = new ObservableCollection<Note>();
    
             CreateNewNote = new Command(() => {
    
    
             });
             MessagingCenter.Subscribe<NotebooksVM, Notebook>(this, "details", async (obj, item) => {
                 Notebook newNotebook = item;
    
                 MainThread.BeginInvokeOnMainThread(async () => {
                     var notes = await Database.ReadAsync<Note>();
                     if (notes != null) {
                         var notebookNotes = notes.Where(n => n.NotebookId == newNotebook.Id);
                         NotesCollection.Clear();
                         foreach (var element in notebookNotes) {
                             NotesCollection.Add(element);
                         }
                     }
                 });
                 
             });


0 Votes 0 ·

Could you share a demo about your issue? Due to I do not have syncfusion environment to make a test.

0 Votes 0 ·
Show more comments

1 Answer

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT edited

Hello,​

Welcome to our Microsoft Q&A platform!

Based on your demo, when you click the sign in the popup Page, then you can navigate to mainPage, you want to transfer data from popup page to the mainPage, am I right?

If so, we do not need to use MessageCenter to transfer data between pages. We can use Navigate way to transfer it like following screenshot.

Login popup page: 108509-image.png then click the sign in button, navigate to the mainPage. 108576-image.png


Here is my edit code in the LoginPage.xaml. Please notice your uppcase for User.Email and User.Password,

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 x:Class="Safe.View.LoginPage"
 xmlns:vm="clr-namespace:Safe.ViewModel"
 xmlns:sfPopup="clr-namespace:Syncfusion.XForms.PopupLayout;assembly=Syncfusion.SfPopupLayout.XForms">

<!--<ContentPage.BindingContext>
<vm:LoginViewModel/>
</ContentPage.BindingContext>-->

<StackLayout>
<Path Aspect="Fill" 
  Stroke="#007fff"
  Fill="#007fff"
  Data="m166.17002,57.2175l501.99997,0l0,104.7864c-272.99998,-68 -170.99998,126.92554 -501.99997,17.24058l0,-122.02698z"/>
<Path Aspect="Uniform"
  Fill="#007fff"
  Stroke="#007fff"
  Data="M55,27.5C55,12.337,42.663,0,27.5,0S0,12.337,0,27.5c0,8.009,3.444,15.228,8.926,20.258l-0.026,0.023l0.892,0.752
c0.058,0.049,0.121,0.089,0.179,0.137c0.474,0.393,0.965,0.766,1.465,1.127c0.162,0.117,0.324,0.234,0.489,0.348
c0.534,0.368,1.082,0.717,1.642,1.048c0.122,0.072,0.245,0.142,0.368,0.212c0.613,0.349,1.239,0.678,1.88,0.98
c0.047,0.022,0.095,0.042,0.142,0.064c2.089,0.971,4.319,1.684,6.651,2.105c0.061,0.011,0.122,0.022,0.184,0.033
c0.724,0.125,1.456,0.225,2.197,0.292c0.09,0.008,0.18,0.013,0.271,0.021C25.998,54.961,26.744,55,27.5,55
c0.749,0,1.488-0.039,2.222-0.098c0.093-0.008,0.186-0.013,0.279-0.021c0.735-0.067,1.461-0.164,2.178-0.287
c0.062-0.011,0.125-0.022,0.187-0.034c2.297-0.412,4.495-1.109,6.557-2.055c0.076-0.035,0.153-0.068,0.229-0.104
c0.617-0.29,1.22-0.603,1.811-0.936c0.147-0.083,0.293-0.167,0.439-0.253c0.538-0.317,1.067-0.648,1.581-1
c0.185-0.126,0.366-0.259,0.549-0.391c0.439-0.316,0.87-0.642,1.289-0.983c0.093-0.075,0.193-0.14,0.284-0.217l0.915-0.764
l-0.027-0.023C51.523,42.802,55,35.55,55,27.5z M2,27.5C2,13.439,13.439,2,27.5,2S53,13.439,53,27.5
c0,7.577-3.325,14.389-8.589,19.063c-0.294-0.203-0.59-0.385-0.893-0.537l-8.467-4.233c-0.76-0.38-1.232-1.144-1.232-1.993v-2.957
c0.196-0.242,0.403-0.516,0.617-0.817c1.096-1.548,1.975-3.27,2.616-5.123c1.267-0.602,2.085-1.864,2.085-3.289v-3.545
c0-0.867-0.318-1.708-0.887-2.369v-4.667c0.052-0.519,0.236-3.448-1.883-5.864C34.524,9.065,31.541,8,27.5,8
s-7.024,1.065-8.867,3.168c-2.119,2.416-1.935,5.345-1.883,5.864v4.667c-0.568,0.661-0.887,1.502-0.887,2.369v3.545
c0,1.101,0.494,2.128,1.34,2.821c0.81,3.173,2.477,5.575,3.093,6.389v2.894c0,0.816-0.445,1.566-1.162,1.958l-7.907,4.313
c-0.252,0.137-0.502,0.297-0.752,0.476C5.276,41.792,2,35.022,2,27.5z M42.459,48.132c-0.35,0.254-0.706,0.5-1.067,0.735
c-0.166,0.108-0.331,0.216-0.5,0.321c-0.472,0.292-0.952,0.57-1.442,0.83c-0.108,0.057-0.217,0.111-0.326,0.167
c-1.126,0.577-2.291,1.073-3.488,1.476c-0.042,0.014-0.084,0.029-0.127,0.043c-0.627,0.208-1.262,0.393-1.904,0.552
c-0.002,0-0.004,0.001-0.006,0.001c-0.648,0.16-1.304,0.293-1.964,0.402c-0.018,0.003-0.036,0.007-0.054,0.01
c-0.621,0.101-1.247,0.174-1.875,0.229c-0.111,0.01-0.222,0.017-0.334,0.025C28.751,52.97,28.127,53,27.5,53
c-0.634,0-1.266-0.031-1.895-0.078c-0.109-0.008-0.218-0.015-0.326-0.025c-0.634-0.056-1.265-0.131-1.89-0.233
c-0.028-0.005-0.056-0.01-0.084-0.015c-1.322-0.221-2.623-0.546-3.89-0.971c-0.039-0.013-0.079-0.027-0.118-0.04
c-0.629-0.214-1.251-0.451-1.862-0.713c-0.004-0.002-0.009-0.004-0.013-0.006c-0.578-0.249-1.145-0.525-1.705-0.816
c-0.073-0.038-0.147-0.074-0.219-0.113c-0.511-0.273-1.011-0.568-1.504-0.876c-0.146-0.092-0.291-0.185-0.435-0.279
c-0.454-0.297-0.902-0.606-1.338-0.933c-0.045-0.034-0.088-0.07-0.133-0.104c0.032-0.018,0.064-0.036,0.096-0.054l7.907-4.313
c1.36-0.742,2.205-2.165,2.205-3.714l-0.001-3.602l-0.23-0.278c-0.022-0.025-2.184-2.655-3.001-6.216l-0.091-0.396l-0.341-0.221
c-0.481-0.311-0.769-0.831-0.769-1.392v-3.545c0-0.465,0.197-0.898,0.557-1.223l0.33-0.298v-5.57l-0.009-0.131
c-0.003-0.024-0.298-2.429,1.396-4.36C21.583,10.837,24.061,10,27.5,10c3.426,0,5.896,0.83,7.346,2.466
c1.692,1.911,1.415,4.361,1.413,4.381l-0.009,5.701l0.33,0.298c0.359,0.324,0.557,0.758,0.557,1.223v3.545
c0,0.713-0.485,1.36-1.181,1.575l-0.497,0.153l-0.16,0.495c-0.59,1.833-1.43,3.526-2.496,5.032c-0.262,0.37-0.517,0.698-0.736,0.949
l-0.248,0.283V39.8c0,1.612,0.896,3.062,2.338,3.782l8.467,4.233c0.054,0.027,0.107,0.055,0.16,0.083
C42.677,47.979,42.567,48.054,42.459,48.132z"/>
<Entry Placeholder="Email"
   Margin="20,10,20,0"/>
<Entry Placeholder="Password"
   Margin="20,10,20,0"/>
<Button Text="Login"
Margin="20,30,20,0"/>
<Label Text="Do not have an account"
   HorizontalTextAlignment="Center"
   FontSize="16"
   TextColor="CornflowerBlue"
   Margin="0,30,0,0">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{x:Binding OpenPopupCommand}"/>
</Label.GestureRecognizers>
</Label>
        <sfPopup:SfPopupLayout Visual="Material" 
   StaysOpen="True"
   ClosePopupOnBackButtonPressed="False"
   x:Name="popUpLayout" IsOpen="{x:Binding DisplayPopUp}">
            <sfPopup:SfPopupLayout.PopupView>
<sfPopup:PopupView HeaderHeight="60"
   AutoSizeMode="Height"
   HeaderTitle="Sign In"
   ShowFooter="False"
   AnimationMode="SlideOnBottom">
<sfPopup:PopupView.PopupStyle>
<sfPopup:PopupStyle HeaderFontAttribute="Bold"
HeaderBackgroundColor="#0D0D41"
HeaderFontSize="20"
HeaderTextAlignment="Center"
HeaderTextColor="White"/>
</sfPopup:PopupView.PopupStyle>
<sfPopup:PopupView.ContentTemplate>
<DataTemplate>
<StackLayout BackgroundColor="CornflowerBlue" 
 Spacing="20"
 Padding="10">
<Entry Placeholder="Email"
                                       Text="{x:Binding User.Email}"/>
<Entry Placeholder="Password"
                                       Text="{x:Binding User.Password}"/>
<Entry Placeholder="Confirm Password"
                                       Text="{x:Binding User.ConfirmPassword}"/>
<Button Text="Sign in"
                                        Command="{x:Binding SignIn}" />
                              
</StackLayout>
</DataTemplate>
</sfPopup:PopupView.ContentTemplate>
</sfPopup:PopupView>
</sfPopup:SfPopupLayout.PopupView>
<sfPopup:SfPopupLayout.Content>
<StackLayout x:Name="mainLayout">
<Button x:Name="clickToShowPopup" Text="ClickToShowPopup" VerticalOptions="Start" HorizontalOptions="FillAndExpand" />
</StackLayout>
</sfPopup:SfPopupLayout.Content>
</sfPopup:SfPopupLayout>
</StackLayout>
</ContentPage>


I register view model in the ``LoginPage.xaml`'s background code.

public partial class LoginPage : ContentPage {
        public LoginPage() {
            InitializeComponent();

            BindingContext = new LoginViewModel(Navigation);
        }
    }


Here is editted LoginViewModel.cs, I use navigation to push new page, then transfer data by MainPage's constructor.

[AddINotifyPropertyChangedInterface]
    public class LoginViewModel {
        public ICommand OpenPopupCommand { get; set; }
        public ICommand SignIn { get; set; }
        public bool DisplayPopUp { get; set; }
        public User User { get; set; }
        public LoginViewModel(INavigation navigation) {
            User = new User();
            OpenPopupCommand = new Command(() => {
                DisplayPopUp = true;
            });
            SignIn = new Command(() => {

                
                  navigation.PushModalAsync(new MainPage(this.User));
                
            });
        }
    }


Then, we can get the User data in the MainPage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage : ContentPage
    {
        public MainPage(User user)
        {
            InitializeComponent();


            UserInfo.Text ="Email:"+ user.Email + "\n Password: " + user.Password;
        }
    }


Here is ``MainPage.xaml`.

<StackLayout Orientation="Vertical">
           
            <Label Text="info" x:Name="UserInfo"></Label>
        </StackLayout>


=============Updated=============

I use your new demo, please change the order of following lines in SelectedNoteBookCommand of NotebooksVM.cs. Push the NotesPage firstly, then send the messsage.

SelectedNoteBookCommand = new Command(async () => {
               
                await Application.Current.MainPage.Navigation.PushAsync(new NotesPage());
                MessagingCenter.Send(this, "details", SelectedNotebook);
                SelectedNotebook = null;
            });


108801-image.png 108764-image.png

Best Regards,

Leon Lu



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



image.png (53.2 KiB)
image.png (13.7 KiB)
image.png (34.4 KiB)
image.png (15.9 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I am so sorry, I forgot to push new changes, I committed, but I did not push

No I don't want that, that part is working fine, let me explain

When you log in, you well see a list of notebooks, that are coming from firebase and are displayed in a ListView. (use a@a.com, 123456)

Each Notebook contain many notes, I am passing the selected notebook, to the "NoteVM.cs" via the MessageCenter.

When a received the selected notebook, I query the data, to get all the notes, corresponding to that particular notebook, but they doesn't appear in my list

Of course I can pass the data to the view, and then to my VM, but I am trying to comunicate my 2 viewModels, and not touch code-behind, that is why I am using the messaging center.

PD: I am very sorry if this has cause any trouble

0 Votes 0 ·

That is fine, please see my updated answer.

0 Votes 0 ·