英文:
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; } = "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);
}
// Sends a message to request the current username, and updates the property
public void RequestCurrentUsername()
{
Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>();
}
// Resets the current username
public void ResetCurrentUsername()
{
Username = null;
}
// A sample request message to get the current username
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 to request the username!"
Click="{x:Bind ViewModel.RequestCurrentUsername}"/>
<Button
Content="Click to reset the local username!"
Click="{x:Bind ViewModel.ResetCurrentUsername}"/>
</StackPanel>
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
我检查了示例,你可能忘记将SenderViewModel
的IsActive设置为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:
<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();
// 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 = "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;
}
// A sample message with a username value
public sealed class UsernameChangedMessage : ValueChangedMessage<string>
{
public UsernameChangedMessage(string value) : base(value)
{
}
}
// A sample request message to get the current username
public sealed class CurrentUsernameRequestMessage : RequestMessage<string>
{
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论