MVVM wpf在视图模型之间传递参数

时间:2016-06-07 10:37:04

标签: c# wpf xaml mvvm

我正在构建一个具有以下设计的应用程序: 一个MainWindowView,带有3" child"视图

  • ProjectView
  • 内容查看
  • PropertiesView3

以下是解释视图的图片链接。

MainWindowView

这些视图是单独的Usercontrols,每个视图都有自己的ViewModel。视图在XAML中声明。

<Grid x:Name="mainGrid" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"  Margin="0">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300"/>
        <ColumnDefinition Width="600*"/>
        <ColumnDefinition Width="300"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="300*"/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>

    <GridSplitter Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" Width="3"/>
    <GridSplitter Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Width="3"/>

    <Menu x:Name="MainMenu" IsMainMenu="True" Grid.ColumnSpan="3" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
        <MenuItem Header="_File" >
            <MenuItem Header="_New..." />
            <Separator />
            <MenuItem Header="_Open..." />
            <Separator />
            <MenuItem Header="_Save" />
            <MenuItem Header="_Save As..." />
            <Separator />
            <MenuItem Header="_Exit"/>
        </MenuItem>
        <MenuItem Header="_Edit">
            <MenuItem Header="_Cut" Command="Cut">
            </MenuItem>
            <MenuItem Header="_Copy" Command="Copy">
            </MenuItem>
            <MenuItem Header="_Paste" Command="Paste">
            </MenuItem>
        </MenuItem>
        <MenuItem Header="_Canvas" />
        <MenuItem Header="_View" />
        <MenuItem Header="_Window" />
        <MenuItem Header="_Help" />
    </Menu>

    <View:ProjectView x:Name="projectView" Grid.Row="1" Grid.Column="0" Margin="-1,0,2,0"/>

    <View:ContentView x:Name="contentView" Grid.Row="1" Grid.Column="1"/>

    <View:PropertiesView x:Name="propertiesView" Grid.Row="1" Grid.Column="2" Margin="2,0,-1,0"/>

    <StatusBar x:Name="statusBar" Grid.ColumnSpan="3" Grid.Row="2">
        <Label x:Name="labelStatus" Content="status" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Width="auto"/>
    </StatusBar>

</Grid>

如何在viewModels之间发送参数?例如:我在ProjectView中有一个列表框,当我选择一个项目时,我想在PropertiesView中更改所选项目的属性。或者在MainWindowView的菜单中,我想创建一个新项目,并将其添加到projectView的列表中。

编辑: 我已经搜索了答案,但找不到适合我问题的解决方案。

2 个答案:

答案 0 :(得分:1)

有很多不同的方法可以做到这一点,但我喜欢活动。

public class usercontrol1 :UserControl{
 public static EventHandler<sometype> NewType;
    public usercontrol1(){
           NewType +=(o,sometype)=>{
               //sometype has the content here.
           }
    }
}

//从另一个控件使用上面的代码

 if(usercontrol1.NewType != null) usercontrol1.Newtype(someInstanceOfSomeType);

有些人抱怨紧密耦合,在这种情况下,您可以创建一个扩展方法来代替所有通知。听众只需连接到扩展方法。

这是一种更“功能性”的解决方案。

public static EventsXM{
    public static RegisterSomeTypeNotification(Action<sometype> Callback){
         userControl1.NewType +=(o,s)=>{
               Callback(s);
         }
    }
    public static NotifyNewData(this sometype data){
         if(usercontrol1.NewType!=null){
              usercontrol1.NetType(data)
         }
    }
}

//to use the XM
sometype.NotifyNewData();  //will send notification
RegisterSomeTypeNotification(data=>{
  //data has the value of sometype here... and is called only when new data arrives
});

虽然两者都应该工作但有些人可能会抱怨悬空事件处理程序......为了解决静态方法中的问题,应该有一种方法来取消注册那个事件的人。

答案 1 :(得分:0)

要在viewModel之间传递对象,您可以使用&#34; messenger&#34;它基于C#事件,它允许您在类之间传递对象。 例如,在MVVM灯中实现了信使系统,允许您以这种方式发送/接收对象。

// Sends a message with a user object from ViewModel 1
User user = new user { Name = "testName" };
Messenger.Default.Send(user);

// Receive the user object in ViewModel 2
Messenger.Default.Register<User>(this, (user) =>
{
    // use "user" object
});

Here是使用MVVM灯的一些示例。