【问题标题】:MVVM wpf pass parameters between view modelsMVVM wpf 在视图模型之间传递参数
【发布时间】:2016-06-07 19:15:29
【问题描述】:

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

  • 项目视图
  • 内容视图
  • PropertiesView3

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

MainWindowView

这些视图是独立的用户控件,每个都有自己的 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>

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

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

【问题讨论】:

  • 使用 eventtaggregator 在视图模型之间进行通信。在事件中传递参数并在事件侦听器中检索它们:blog.magnusmontin.net/2014/02/28/…
  • 如果视图之间共享相同的 ViewModel,则无需做任何特别的事情。我有时会使用适合多个视图的 VM 来简化事情。
  • 在这一刻,我找到的所有解决方案对我来说都很难。所以我构建了一个包含所有其他视图的视图。但这对我有用。

标签: c# wpf xaml mvvm


【解决方案1】:

要在视图模型之间传递对象,您可以使用“信使”,它基于 C# 事件,它允许您在类之间传递对象。 例如,在 MVVM light 中实现了一个信使系统,允许您以这种方式发送/接收对象。

// 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 光的示例。

【讨论】:

  • 又好又简单...太棒了!
【解决方案2】:

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

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
});

虽然两者都应该工作,但有些人可能会抱怨悬空的事件处理程序......要在静态方法中解决这个问题,应该有一种方法可以取消注册任何监听该事件的人。

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    相关资源
    最近更新 更多