Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MVVM中将对象从父视图传递到子视图_C#_Wpf_Windows_Mvvm_Communication - Fatal编程技术网

C# 在MVVM中将对象从父视图传递到子视图

C# 在MVVM中将对象从父视图传递到子视图,c#,wpf,windows,mvvm,communication,C#,Wpf,Windows,Mvvm,Communication,我目前正试图进入WPF和MVVM,但最近遇到了一个我不知道如何解决的问题。我是新来的,所以如果有什么不对劲,请告诉我 我有一个ParentView及其ParentViewModel。ParentView包含两个视图SubViewA和SubViewB,它们都有自己的视图模型。这是my ParentView.xaml: <local:ViewBase.DataContext> <local:ParentViewModel x:Name="Model" /> </

我目前正试图进入WPF和MVVM,但最近遇到了一个我不知道如何解决的问题。我是新来的,所以如果有什么不对劲,请告诉我

我有一个ParentView及其ParentViewModel。ParentView包含两个视图SubViewA和SubViewB,它们都有自己的视图模型。这是my 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>
<local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" SomeProperty="{Binding ElementName=Model, Path=WhatIWantThePropertyToBe}" />

我想做的是:SubViewModelB有一个绑定到SubViewB的属性。我想在ParentViewModel中发生特定事件时更改该属性。我想这应该通过将SubViewModelB中的属性绑定到ParentViewModel中的属性来实现,但我不确定如何实现?我在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>
<local:SubViewB Visibility="{Binding ElementName=Model, Path=SubViewBVisibility}" SomeProperty="{Binding ElementName=Model, Path=WhatIWantThePropertyToBe}" />

但这对我来说毫无意义。 那么我该如何解决这个问题呢?我知道我可以通过MVVM light toolkit中的消息传递来实现这一点,但这似乎有点不适合我正在尝试做的事情。有什么建议吗


谢谢

您的
父视图模型
中会有
子视图模型
的实例,对吗?如果这样做,您只需在
ParentViewModel
中捕获事件,并手动更改
SubViewModel
的特定属性值

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

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

试试这样的

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

听起来这是一个很好的解决方案。有一些很好的实现,比如or提供的(非常轻量级)

作为一个代码示例,您可以这样做(使用Prism,未经测试的代码)

公共类ParentViewModel
{
私有事件聚合器;
public ParentViewModel(IEventAggregator事件聚合器)
{
this.eventAggregator=eventAggregator;
}
公共无效PublishSomeEvent()
{
//出现条件时,向任何订阅服务器发布事件
//那可能是在听
this.eventAggregator.GetEvent()
.Publish(newsomeevent(“helloworld!”);
}
}
公共类子视图模型
{
私有事件聚合器;
公共子视图模型(IEventAggregator事件聚合器)
{
eventAggregator.GetEvent.SomeEvent(OnSomeEventOccessed);
}
OnSomeEventOccessed(SomeEvent参数)上的公共无效
{
//此方法在ParentViewModel发布事件时调用
控制台写入线(参数可选消息);
}
}
您需要单独声明事件。比如,我用这个

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

    public string OptionalMessage { get { return optionalMessage; } } 
}
publicsomeevent:CompositePresentationEvent
{
公共事件(字符串可选消息)
{
this.optionalMessage=optionalMessage;
}
公共字符串OptionalMessage{get{return OptionalMessage;}}
}

感谢您的回复。很遗憾,没有,我没有直接访问子视图模型的权限。我的视图自己创建模型。我认为这是MVVM中合适的方式,而且它似乎是视图与其viewmodel之间存在明确关系的唯一方式。谢谢。去了信使的方法,但仍然有帮助。谢谢!我想我可以这样做,但这真的是正确的方式吗?对于一个实际耦合的问题,这似乎是一个非常解耦的解决方案。例如,如果我有多个ParentView,每个都有自己的子视图,那么这个解决方案就不起作用了,不是吗?不过,我只有一个ParentView,所以我想这应该没问题:-)谢谢!这就是路。仅仅因为它们是子视图并不意味着它们需要了解它们的父视图。对于多个ParentView,您可以让ParentView向其子视图传递Guid或某种标识符,该子视图也作为激发事件的一部分传递。然后,他们所需要做的就是检查该标识符,看看所触发的事件是否适合他们。结合依赖注入,它真的让生活变得简单。如果你只是想要轻量的,我会和蒂尼辛格一起去。它是一个单一的cs文件,我已经在生产系统中成功地使用了它。如果这是最佳实践,我将使用它:-)已经在应用程序的其他地方使用了MVVM light messenger系统,因此它也很容易实现;-)谢谢你们这么快responses@MarioEmantsal你可以尝试的另一件事是多重绑定,但我不推荐太多的Xaml黑客来让你的应用程序在视觉上工作。最好是在代码中明确,并围绕代码进行一些单元测试。另一种方法是提取一个名为VisibilityManager的类,并将其作为依赖项(通过接口)注入到两个viewmodel中,以根据逻辑/条件处理viewmodel之间的可见性