4

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

我有一个 ParentView 和它的 ParentViewModel。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 轻型工具包中的消息传递来做到这一点,但这似乎不适合我正在尝试做的事情。有什么建议么?

谢谢

4

2 回答 2

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; } } 
}
于 2012-05-28T12:57:16.703 回答
1

你会SubViewModel在你的ParentViewModel权利的实例?如果你这样做了,那么你可以简单地捕获事件ParentViewModel并手动更改SubViewModel.

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

另一种方法是直接将 SubView 的属性与 ParentViewModel 中的属性绑定

尝试这样的事情

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type Window}}, Path=DataContext.ParentViewModelProperty}"
于 2012-05-28T12:16:43.967 回答