0

我有一个带有 Caliburn.Micro 的 WPF 应用程序。主要的 ViewModel 是 ShellViewModel。它包含一个选项卡控件,每个选项卡都包含一个用户控件。我需要从该内部用户控件访问 ShellViewModel 的属性。

var par = ((MyApp.ShellViewModel)((Screen)Parent).MyProperty;

ShellViewModel 虽然未知。你能告诉我如何访问它吗?

谢谢。

4

2 回答 2

2
var parent = IoC.Get<ShellViewModel>();

我目前无法验证该语法,但我认为它是正确的。

于 2012-12-21T02:22:37.253 回答
2

好的,从您的评论看来,您在外壳上有一个组合框,需要影响其中一个选项卡上显示的内容。

要在 ViewModel 之间进行通信,您始终可以使用EventAggregatorCM 的一部分并实现可以利用的订阅者模式

例如

在您的 shell VM 上,您可以创建聚合器的静态实例或创建一个单独的静态类,该类将为应用程序提供聚合器

static class AggregatorProvider 
{
    // The event aggregator
    public static EventAggregator Aggregator = new EventAggregator();
}

class ShellViewModel : Conductor<IScreen>
{
    // When the combo box selection changes...
    public void SelectionChanged(object SomeValue) 
    {
        // Publish an event to all subscribers
        AggregatorProvider.Aggregator.Publish(new SelectionChangedMessage(SomeValue));
    }
}

您可以SelectionChanged使用标准操作消息或约定来处理组合框(我不确定 CM 默认对组合应用哪些约定,因此我将在示例中显示显式绑定)

<ComboBox x:Name="MyCombo" cal:Message.Attach="[Event SelectionChanged] = [Action SelectionChanged(MyCombo)" />

希望如果应用了正确的约定,您应该将所选项目传递给该方法

您的子虚拟机只需要订阅聚合器并实现 IHandle,其中 T 是它应该处理的消息类型

class ChildViewModel : Screen, IHandle<SelectionChangedMessage>
{
    public ChildViewModel() 
    {
        // Subscribe to the aggregator so we receive messages from it
        AggregatorProvider.Aggregator.Subscribe(this);
    }

    // When we receive a SelectionChangedMessage...
    public void Handle(SelectionChangedMessage message) 
    {
        // Do something with the new selection
    }
}

SelectionChangedMessage可以是:

class SelectionChangedMessage 
{
    public object NewValue { get; private set; }

    public SelectionChangedMessage(object newValue) 
    {
        NewValue = newValue;
    }
}

显然,上面可能是一个泛型类型,因此您可以强烈键入NewValue参数 - 然后您发布的消息可以是任何东西,所以这取决于您

值得指出的是,您可以Unsubscribe从聚合器中控制它何时接收通知。聚合器无论如何都使用弱引用,因此您无需过多担心取消订阅,但这确实意味着您可以控制对象何时接收消息(即通过订阅OnActivate和取消订阅在不活动时停止侦听OnDeactivate)。

于 2012-12-21T19:08:04.323 回答