如何在Caliburn.Micro应用程序中访问ShellViewModel?

时间:2012-12-20 20:16:12

标签: c# wpf caliburn.micro

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

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

虽然不知道ShellViewModel。你能告诉我怎样才能访问它吗?

感谢。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

好的,你的评论听起来好像你的shell上有一个组合框需要影响其中一个标签上显示的内容。

要在ViewModel之间进行通信,您始终可以使用属于CM的EventAggregator并实现可以利用的订阅者模式

e.g。

在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)" />

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

您的子VM只需要订阅聚合器并实现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,以便您可以控制何时收到通知。聚合器无论如何都使用弱引用,因此您不必过于担心取消订阅,但它确实意味着您可以控制对象何时接收消息(即通过订阅{{1}时停止侦听}并取消订阅OnActivate)。