如何在WinUI 3中使用MVVM Toolkit请求消息?

huangapple go评论82阅读模式
英文:

How to request message in WinUI 3 with MVVM Toolkit?

问题

目标和情况:

我只是按照MVVM Toolkit示例应用程序中的“请求消息”示例操作,但它不起作用。

问题:

我的“用户名”和RequestCurrentUsername()变为null(请参见图像)或下面的代码。

也许我的代码只是错误的,或者是因为我在UserSenderViewModel中没有IsActive导致的错误?我该怎么做?他们在使用OnActivated()

调试模式中的错误截图

ViewModel

https://github.com/CommunityToolkit/MVVM-Samples/blob/master/samples/MvvmSample.Core/ViewModels/MessengerPageViewModel.cs

public class ViewModelRequestMessenger: ObservableObject
{

    public class UserSenderViewModel : ObservableRecipient
    {
        public string Username { get; private set; } = "Bob";

        protected override void OnActivated()
        {
            Messenger.Register<UserSenderViewModel, CurrentUsernameRequestMessage>(this, (r, m) => m.Reply(r.Username));
        }
    }


    private string username;

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

    // 发送消息以请求当前用户名,并更新属性
    public void RequestCurrentUsername()
    {
        Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>();
    }

    // 重置当前用户名
    public void ResetCurrentUsername()
    {
        Username = null;
    }

    // 一个用于获取当前用户名的示例请求消息
    public sealed class CurrentUsernameRequestMessage : RequestMessage<string>
    {
    }

}

MainWindow.xaml

<StackPanel Spacing="8">
    <StackPanel.DataContext>
        <viewmodels:ViewModelRequestMessenger x:Name="ViewModel"/>
    </StackPanel.DataContext>
    <TextBlock Text="{x:Bind ViewModel.Username, Mode=OneWay}"/>
    <Button
    Content="点击请求用户名!"
    Click="{x:Bind ViewModel.RequestCurrentUsername}"/>
    <Button
    Content="点击重置本地用户名!"
    Click="{x:Bind ViewModel.ResetCurrentUsername}"/>

</StackPanel>

MainWindow.xaml.cs 代码

public sealed partial class MainWindow : Window
{
    //private ViewModelRequestMessenger ViewModel { get; } = new();
    
    public MainWindow()
    {
        this.InitializeComponent();
        //this.ViewModel = new ViewModelRequestMessenger(); 
    }

}
英文:

Goal and sitatuion:

I Just follow the ‘Request Messages’ examples from MVVM Tooolkit Sample app but it doesn't work.

The problem:

My ‘Username’ and RequestCurrentUserName() becomes null (see the image) or the below code.

Maybe my code is just wrong or can I get the error because I don’t have IsActive on my UserSenderViewModel Somewhere? And how should I do it? They are using OnActivated().

Screenshot of error in debugging mode

ViewModel

https://github.com/CommunityToolkit/MVVM-Samples/blob/master/samples/MvvmSample.Core/ViewModels/MessengerPageViewModel.cs

public class ViewModelRequestMessenger: ObservableObject
{

    public class UserSenderViewModel : ObservableRecipient
    {
        public string Username { get; private set; } = &quot;Bob&quot;;

        protected override void OnActivated()
        {
            Messenger.Register&lt;UserSenderViewModel, CurrentUsernameRequestMessage&gt;(this, (r, m) =&gt; m.Reply(r.Username));
        }
    }


    private string username;

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

    // Sends a message to request the current username, and updates the property
    public void RequestCurrentUsername()
    {
        Username = WeakReferenceMessenger.Default.Send&lt;CurrentUsernameRequestMessage&gt;();
    }

    // Resets the current username
    public void ResetCurrentUsername()
    {
        Username = null;
    }

    // A sample request message to get the current username
    public sealed class CurrentUsernameRequestMessage : RequestMessage&lt;string&gt;
    {
    }

}

MainWindow.xaml

     &lt;StackPanel Spacing=&quot;8&quot;&gt;
        &lt;StackPanel.DataContext&gt;
            &lt;viewmodels:ViewModelRequestMessenger x:Name=&quot;ViewModel&quot;/&gt;
        &lt;/StackPanel.DataContext&gt;
        &lt;TextBlock Text=&quot;{x:Bind ViewModel.Username, Mode=OneWay}&quot;/&gt;
        &lt;Button
        Content=&quot;Click to request the username!&quot;
        Click=&quot;{x:Bind ViewModel.RequestCurrentUsername}&quot;/&gt;
        &lt;Button
        Content=&quot;Click to reset the local username!&quot;
        Click=&quot;{x:Bind ViewModel.ResetCurrentUsername}&quot;/&gt;

    &lt;/StackPanel&gt;

Code-Behind MainWindow.xaml.cs

    public sealed partial class MainWindow : Window
    {
        //private ViewModelRequestMessenger ViewModel { get; } = new();
        
        public MainWindow()
        {
            this.InitializeComponent();
            //this.ViewModel = new ViewModelRequestMessenger(); 
        }

    }

答案1

得分: 0

我检查了示例,你可能忘记将SenderViewModelIsActive设置为True

根据示例创建了一个简单的演示,它正常工作。你可以查看以下代码。

Xaml:

<StackPanel Spacing="8">
    <TextBlock Text="{x:Bind ViewModel.Username, Mode=OneWay}"/>
    <Button
        Content="Click to request the username!"
        Click="{x:Bind ViewModel.RequestCurrentUsername}"/>
</StackPanel>

Code-behind:

public sealed partial class MainWindow : Window
{
    public MessengerRequestModel ViewModel { get; set; }

    public MainWindow()
    {
        this.InitializeComponent();
        ViewModel = new MessengerRequestModel();
        // 你可能漏掉了这一部分
        ViewModel.SenderViewModel.IsActive = true;
    }
}
public class MessengerRequestModel : ObservableObject
{
    public ICommand RequestCurrentUsernameCommand { get; }

    public UserSenderViewModel SenderViewModel { get; } = new();

    // 用于发送用户名消息的简单视图模型
    public class UserSenderViewModel : ObservableRecipient
    {
        public UserSenderViewModel()
        {
            SendUserMessageCommand = new RelayCommand(SendUserMessage);
        }

        public ICommand SendUserMessageCommand { get; }

        private string username = "Bob";

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

        protected override void OnActivated()
        {
            Messenger.Register<UserSenderViewModel, CurrentUsernameRequestMessage>(this, (r, m) => m.Reply(r.Username));
        }

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

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

    private string? username;

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

    public void RequestCurrentUsername()
    {
        Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>();
    }

    public void ResetCurrentUsername()
    {
        Username = null;
    }

    // 一个带有用户名值的示例消息
    public sealed class UsernameChangedMessage : ValueChangedMessage<string>
    {
        public UsernameChangedMessage(string value) : base(value)
        {
        }
    }

    // 一个用于获取当前用户名的示例请求消息
    public sealed class CurrentUsernameRequestMessage : RequestMessage<string>
    {
    }
}
英文:

I checked the sample, and you might forget to set the IsActive of the SenderViewModel to True.

Made a simple demo based on the sample and it works correctly. You could check the following code.

Xaml:

  &lt;StackPanel Spacing=&quot;8&quot;&gt;
        &lt;TextBlock Text=&quot;{x:Bind ViewModel.Username, Mode=OneWay}&quot;/&gt;
        &lt;Button
    Content=&quot;Click to request the username!&quot;
    Click=&quot;{x:Bind ViewModel.RequestCurrentUsername}&quot;/&gt;
  &lt;/StackPanel&gt;

Code-behind:

public sealed partial class MainWindow : Window
{
    public MessengerRequestModel ViewModel { get; set; }

    public MainWindow()
    {
        this.InitializeComponent();
        ViewModel = new MessengerRequestModel();
        // you might miss this 
        ViewModel.SenderViewModel.IsActive = true;
    }
   
}

public class MessengerRequestModel : ObservableObject
{
    public ICommand RequestCurrentUsernameCommand { get; }

    public UserSenderViewModel SenderViewModel { get; } = new();


    // Simple viewmodel for a module sending a username message
    public class UserSenderViewModel : ObservableRecipient
    {
        public UserSenderViewModel()
        {
            SendUserMessageCommand = new RelayCommand(SendUserMessage);
        }

        public ICommand SendUserMessageCommand { get; }

        private string username = &quot;Bob&quot;;

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

        protected override void OnActivated()
        {
            Messenger.Register&lt;UserSenderViewModel, CurrentUsernameRequestMessage&gt;(this, (r, m) =&gt; m.Reply(r.Username));
        }

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

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

  

    private string? username;

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

    public void RequestCurrentUsername()
    {
        Username = WeakReferenceMessenger.Default.Send&lt;CurrentUsernameRequestMessage&gt;();
    }

    public void ResetCurrentUsername()
    {
        Username = null;
    }

    // A sample message with a username value
    public sealed class UsernameChangedMessage : ValueChangedMessage&lt;string&gt;
    {
        public UsernameChangedMessage(string value) : base(value)
        {
        }
    }

    // A sample request message to get the current username
    public sealed class CurrentUsernameRequestMessage : RequestMessage&lt;string&gt;
    {
    }

} 

huangapple
  • 本文由 发表于 2023年6月26日 15:04:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76554249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定