将对象从父视图传递到MVVM中的子视图

时间:2012-05-28 11:43:27

标签: c# wpf windows mvvm communication

我目前正在尝试进入WPF和MVVM,但我最近遇到了一个我不知道如何解决的问题。我是新手,所以如果不是应该的话,请告诉我。

我有一个带有ParentViewModel的ParentView。 ParentView拥有两个视图SubViewA和SubViewB,它们都有自己的ViewModel。这是我的ParentView.xaml:

<local:ViewBase.DataContext>
    <local:ParentViewModel x:Name="Model" />
</local:ViewBase.DataContext>

<Grid>
    <local:SubViewA Visibility="{Binding ElementName=Model, Path=SubViewAVisibility}" />
    <local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" />
</Grid>

我想做什么:SubViewModelB有一个绑定到SubViewB的属性。我想在ParentViewModel中发生某个事件时更改该属性。我想这应该通过将SubViewModelB中的属性绑定到ParentViewModel中的属性来完成,但我不确定如何?我在ParentView.xaml中尝试了类似下面的内容:

<local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" SomeProperty="{Binding ElementName=Model, Path=WhatIWantThePropertyToBe}" />

但那让我无处可去。 那么我该如何解决这个问题呢?我知道我可以通过MVVM轻量级工具包中的消息传递来实现它,但这似乎与我想要做的事情不相称。有什么建议吗?

由于

2 个答案:

答案 0 :(得分:3)

这对EventAggregator模式来说是一个很好的解决方案。有一些很棒的实现,例如由Microsoft PrismTinyMessenger提供的(非常轻量级)

作为一个代码示例,你会做这样的事情(使用Prism,未经测试的代码)

public class ParentViewModel
{
    private IEventAggregator eventAggregator;

    public ParentViewModel(IEventAggregator eventAggregator)
    {
       this.eventAggregator = eventAggregator;
    }

    public void PublishSomeEvent()
    {
        // When a condition occurs, publish an event any subscribers 
        // that may be listening
        this.eventAggregator.GetEvent<SomeEvent>()
            .Publish(new SomeEvent("Hello World!")));
    }
}

public class SubViewModel
{
    private IEventAggregator eventAggregator;

    public SubViewModel(IEventAggregator eventAggregator)
    {
       eventAggregator.GetEvent<SomeEvent>.SomeEvent(OnSomeEventOccurred);
    }

    public void OnSomeEventOccurred(SomeEvent arg)
    {
        // This method called when ParentViewModel publishes the event
        Console.WriteLine(arg.OptionalMessage);
    }
}

您需要单独声明该事件。例如,我使用这个

public SomeEvent : CompositePresentationEvent<SomeEvent>
{
    public SomeEvent(string optionalMessage)
    {
        this.optionalMessage = optionalMessage;
    }

    public string OptionalMessage { get { return optionalMessage; } } 
}

答案 1 :(得分:1)

您的SubViewModel权利中会有ParentViewModel的实例吗?如果您这样做,则可以在ParentViewModel中捕获事件并手动更改SubViewModel的特定属性值。

我不确定这是否是完美的方式,但这应该做的工作。

另一种方法是直接使用ParentViewModel

中的属性绑定SubView的属性

尝试这样的事情

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type Window}}, Path=DataContext.ParentViewModelProperty}"
相关问题