CommunityToolkit / MVVM-Samples

Sample repo for MVVM package
Other
1.15k stars 224 forks source link

Messenger Sample with ReceiverViewModel doesnt work in Winui 3 #124

Closed ghost closed 1 year ago

ghost commented 1 year ago

Had there been any update on how to receive messenger? I had make the "Sending Messages" example in winui 3.

I can show TextBlock Text="{x:Bind ViewModel.SenderViewModel.Username, Mode=OneWay}"/>

But not from the receiver: TextBlock Text="{x:Bind ViewModel.ReceiverViewModel.Username, Mode=OneWay}"/>

public class MessengerPageViewModel : SamplePageViewModel
{

    //https://github.com/CommunityToolkit/MVVM-Samples/blob/master/samples/MvvmSample.Core/ViewModels/MessengerPageViewModel.cs#LL31C1-L32C1
    public UserSenderViewModel SenderViewModel { get; } = new();

    public UserReceiverViewModel ReceiverViewModel { get; } = new();

    public class UserSenderViewModel : ObservableRecipient
    {
        public UserSenderViewModel()
        {
        }

        private string username = "Bob";

        public string Username
        {
            get => username;
            private set => SetProperty(ref username, value);
        }

        public void SendUserMessage()
        {
            Username = Username == "Bob" ? "Alice" : "Bob";

            Messenger.Send(new UsernameChangedMessage(Username));
        }
    }

    // Simple viewmodel for a module receiving a username message
    public class UserReceiverViewModel : ObservableRecipient
    {
        private string username = "";

        public string Username
        {
            get => username;
            private set => SetProperty(ref username, value);
        }

        protected override void OnActivated()
        {
            Messenger.Register<UserReceiverViewModel, UsernameChangedMessage>(this, (r, m) => r.Username = m.Value);
        }
    }

    private string? username;

    public string? Username
    {
        get => username;
        private set => SetProperty(ref username, value);
    }

    public sealed class UsernameChangedMessage : ValueChangedMessage<string>
    {
        public UsernameChangedMessage(string value) : base(value)
        {
        }
    }

}
<Window
    x:Class="RandomMVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:RandomMVVM"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewmodels="using:RandomMVVM.ViewModels"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <StackPanel.DataContext>
            <viewmodels:MessengerPageViewModel x:Name="ViewModel"/>
        </StackPanel.DataContext>
        <Border>
            <StackPanel>
                <TextBlock Text="{x:Bind ViewModel.SenderViewModel.Username, Mode=OneWay}"/>
                <Button
                Content="Click to send a message!"
                Click="{x:Bind ViewModel.SenderViewModel.SendUserMessage}"/>
            </StackPanel>
        </Border>
        <Border>
            <StackPanel>
                <TextBlock Text="{x:Bind ViewModel.ReceiverViewModel.Username, Mode=OneWay}"/>
            </StackPanel>
        </Border>
    </StackPanel>
</Window>
yuexiliuli commented 1 year ago

I have a similar issue in my UWP app as you did. Have you resolved it?

ghost commented 1 year ago

I have a similar issue in my UWP app as you did. Have you resolved it?

Yes.

The ReceiverViewModel constructor:

public UserReceiverViewModel() {
    IsActive = true;
}
yuexiliuli commented 1 year ago

Thank you very much for your answer. It worked perfectly and solved my problem from yesterday. While looking for a solution, I also found other methods that might be helpful to you. On YouTube, https://www.youtube.com/watch?v=vD17OetzGXc, the author uses WeakReferenceMessenger.

ghost commented 1 year ago

Thank you very much for your answer. It worked perfectly and solved my problem from yesterday. While looking for a solution, I also found other methods that might be helpful to you. On YouTube, https://www.youtube.com/watch?v=vD17OetzGXc, the author uses WeakReferenceMessenger.

Yes it is probably better :)

Thanks