首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用ReactiveUI MessageBus模式在两个UserControls之间进行通信?

如何使用ReactiveUI MessageBus模式在两个UserControls之间进行通信?
EN

Stack Overflow用户
提问于 2020-03-04 06:01:12
回答 2查看 701关注 0票数 0

我正在尝试在wpf项目中使用ReactiveUI框架。详细地说,我尝试使用MessageBus模式在两个不同的视图模型之间进行通信。在下面的简化示例中,当我单击MainWindowView按钮insert into MainWindowView时,我尝试更新UserControl标签。按钮单击由调用UserControlViewModel方法的ReactiveUI BindCommand管理。该方法通过MessageBus ReactiveUI机制发送消息。MainWindowViewModel侦听消息并更新显示窗口标题的MainWindowView上的标签标题。我不知道为什么这不管用。

下面是代码:

MainWindowView (Xaml):

代码语言:javascript
运行
复制
<rxui:ReactiveWindow x:Class="TestMessageBus.MainWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestMessageBus"
        xmlns:rxui="http://reactiveui.net"
        x:TypeArguments="local:MainWindowViewModel"             
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <Label x:Name="TitleLabel" HorizontalAlignment="Center"/>
        <local:UserControlView/>
    </StackPanel>
</rxui:ReactiveWindow>

MainWindowView (代码隐藏):

代码语言:javascript
运行
复制
namespace TestMessageBus
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindowView : ReactiveWindow<MainWindowViewModel>
    {
        public MainWindowView()
        {
            InitializeComponent();

            ViewModel = new MainWindowViewModel();

            this.WhenActivated(disposable =>
            {
                this.OneWayBind(ViewModel, vm => vm.Title, v => v.TitleLabel.Content)
                    .DisposeWith(disposable);
            });
        }
    }
}

MainWindowViewModel:

代码语言:javascript
运行
复制
namespace TestMessageBus
{
    public class MainWindowViewModel : ReactiveObject
    {
        public string Title { get; set; }

        public MainWindowViewModel()
        {

            MessageBus.Current.Listen<string>("Contract1").Subscribe(x => MessageSend(x));

        }

        private void MessageSend(string title)
        {
            Title = title;
        }
    }
}

UserControlView (Xaml):

代码语言:javascript
运行
复制
<rxui:ReactiveUserControl x:Class="TestMessageBus.UserControlView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestMessageBus"
             xmlns:rxui="http://reactiveui.net"
             x:TypeArguments="local:UserControlViewModel" 
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="200">
    <Grid>
        <Button x:Name="ButtonTest">TEST</Button>
    </Grid>
</rxui:ReactiveUserControl>

UserControlView (代码隐藏):

代码语言:javascript
运行
复制
namespace TestMessageBus
{
    /// <summary>
    /// Interaction logic for UserControlView.xaml
    /// </summary>
    public partial class UserControlView : ReactiveUserControl<UserControlViewModel>
    {
        public UserControlView()
        {
            InitializeComponent();

            ViewModel = new UserControlViewModel();

            this.WhenActivated(disposable =>
            {
                this.BindCommand(ViewModel, vm => vm.ClickCommand, v => v.ButtonTest).DisposeWith(disposable);
            });
        }
    }
}

UserControlViewModel:

代码语言:javascript
运行
复制
namespace TestMessageBus
{
    public class UserControlViewModel: ReactiveObject
    {
        public ReactiveCommand<Unit, Unit> ClickCommand { get; set; }

        public UserControlViewModel()
        {
            ClickCommand = ReactiveCommand.Create(ClickButton);


        }

        private void ClickButton()
        {
            MessageBus.Current.SendMessage("TITOLO", "Contract1");
        }
    }
}

我希望在MainWindow标签中看到"TITOLO“字符串,但这并没有发生。有人能解释一下为什么吗?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2020-03-04 14:36:58

首先我想指出的是,即使框架提供了MessageBus实现,我们也不推荐使用它。

在您的示例中,我没有看到您注册消息源。

你应该有一个对RegisterMessageSource的调用,它接受一个IObservable,在这种情况下,我认为应该是你点击了按钮。

类似于:

代码语言:javascript
运行
复制
MessageBus.Current.RegisterMessageSource(ButtonTest.Events().Clicked)

其中Events().Clicked只是按钮单击事件的一个可观察的包装器。

ReactiveUI Website上有一个例子

票数 1
EN

Stack Overflow用户

发布于 2020-10-24 07:21:39

这是一种潜在的方法,但我不确定它是否符合反应式UI的最佳实践。对我来说,问题是SubjectIObservableIObserver搞得一团糟。

代码语言:javascript
运行
复制
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Diagnostics;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        private static string GetSomeData() => "Hi";

        [TestMethod]
        public async Task TestMethod8()
        {
            var subject = new Subject<string>();

            //Create a class and inject the subject as IObserver
            new Publisher(subject);

            //Create a class and inject the subject as IObservable
            new Subscriber(subject);
            new Subscriber(subject);
            new Subscriber(subject);

            //Run the loop for 10 seconds
            await Task.Delay(10000);
        }

        class Publisher
        {
            public Publisher(IObserver<string> observer)
            {
                Task.Run(async () =>
                {
                    //Loop forever
                    while (true)
                    {
                        //Get some data, publish it with OnNext and wait 500 milliseconds
                        observer.OnNext(GetSomeData());
                        await Task.Delay(500);
                    }
                });
            }
        }

        class Subscriber
        {
            //Listen for OnNext and write to the debug window when it happens
            public Subscriber(IObservable<string> observable) => observable.Subscribe((s) => Debug.WriteLine(s));
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60516166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档