【问题标题】:Caliburn.micro parent->child and child->parent interactionsCaliburn.micro 父->子和子->父交互
【发布时间】:2019-01-19 22:31:24
【问题描述】:

我正在使用 Caliburn.micro 开发 WPF 应用程序。在那里,我有一个扩展了 Conductor 的 mainViewModel 和两个扩展了 Screen 的 subviewModel。这两个视图模型由我的 MainViewModel 中的选项卡控件激活。我有属于 MainViewModel 的字符串,我需要将这些字符串传递给两个 subViewModel。我需要传递给 subViewModels 的字符串在 MainView 中绑定到文本框。我想将这些字符串传递给 subViewModel,即使这些字符串从 MainViewModel 更改,我也需要更新我的 subViewModels。现在我将 MainViewModel 作为每个 subViewModel 的构造函数中的参数,但我很确定有更好的方法 基本上我想将子属性绑定到父属性,如果属性在父视图模型或子视图模型中发生更改,则报告它们中的任何一个。 你能给我指明一个好的方向吗?

【问题讨论】:

    标签: c# mvvm parent-child caliburn.micro


    【解决方案1】:

    您可以利用 EventAggregators 来实现这一点。

    对于那些不熟悉的人,事件聚合器是一种提供 将对象从一个实体发布到另一个实体的能力 松散的时尚。

    您可以阅读更多关于事件聚合器here

    首先定义包含要传递的消息的 CustomMessage。

    public class CustomMessage
    {
        public string String1 { get; set; }
    }
    

    现在您继续到 ParentViewModel 并创建事件聚合器的实例。

    private IEventAggregator _eventAggregator;
    [ImportingConstructor]
    public ShellViewModel(IEventAggregator eventAggregator)
    {
    _eventAggregator = eventAggregator;
    _eventAggregator.Subscribe(this);
    }
    

    在绑定到文本框的属性的 Setter 中,您现在可以添加代码以使用事件聚合器发布消息。

    例如,

    public string String1
    {
        get => _string1;
        set
        {
            if (_string1.Equals(value)) return;
    
            _string1 = value;
            _eventAggregator.PublishOnUIThread(new CustomMessage
            {
                String1 = _string1,
            });
    
        }
    
    }
    

    现在您前往您的子视图模型并订阅事件聚合器。

    private IEventAggregator _eventAggregator;
    [ImportingConstructor]
    public SecondWinViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.Subscribe(this);
    }
    

    为了订阅特定消息(在本例中为 CustomMessage),您需要实现接口 IHandle。

    [Export(typeof(SecondWinViewModel))]
    public class SecondWinViewModel : Screen, IHandle<CustomMessage>
    

    该界面需要一个方法,您可以使用该方法接收消息并更新子窗口中所需的属性。

    public void Handle(CustomMessage message)
    {
        String1 = message.String1;
        NotifyOfPropertyChange(nameof(String1));
    }
    

    您可以通过在 CustomMessage 中添加更多属性来对多个参数执行相同的操作。同理,您可以将消息从 Child Vm 传递到 Parent Vm。

    【讨论】:

    • 非常感谢,看起来这是可行的;)这也可能与结构有关吗?我有很多字符串要订阅和发布,我必须在另一个 ViewModel 中阅读这些字符串。所以我想创建一个结构或列表,然后当任何字符串发生更改时,我可以更新所有自动监听的文本框。
    • @M00 结构也应该可以工作。对于您提到的情况, List> 应该是理想的
    • @M00 很高兴为您提供帮助。如果它帮助您解决问题,请将其标记为答案。
    猜你喜欢
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    相关资源
    最近更新 更多