Viewmodel的多个实例

时间:2011-03-21 15:40:45

标签: wpf mvvm

我是WPF和MVVM的新手(这是我在WPF中的第一个项目)。我正在处理的项目应该接受一些搜索条件,并在网格中显示结果。要构造查询我正在使用动态LINQ查询。我似乎在管理ProjectSearchViewModel的实例时遇到问题,该实例对应于负责收集搜索条件和执行查询的视图。创建MainWindowViewModel时会创建一个实例。这将创建所有其他viewmodel实例。这就是我的期望。但是当显示MainWindow的时候,我得到另一个ProjectSearchViewModel,我想从绑定。

一般的想法是:

  1. 搜索条件填入ProjectSearchView。

  2. 按下加载命令后,我使用Reactive Extensions方法发送SearchResultMessage。

  3. MainWindowViewModel

  4. 接收消息
  5. MainWindowViewModel正在查询ProjectSearchViewModel.SearchResult,并将IObservable List分配给AllProjectsViewModel.AllProjects,它绑定到数据网格以显示结果(AllProjectView负责显示带有结果项目列表的网格)

    < / LI>

    问题是SearchResultMessage的参数填充和发送发生在ProjectSearchViewModel的一个实例中,并且从MainWindowViewModel实际查询SearchResult发生在另一个实例中,其中所有搜索条件都是空的。

    我想我别无选择,只能发布我的代码:这里是它的删节版本,省略了一些iDisposable管道等等。对于我的模型,我使用Entity Framework 4。

    正如我所提到的,我是一个全新的人,所以如果有人看到任何公然无视常识的话,请指好我。

    Imports Cheminator.ViewModel

    Partial Public Class App
    
        Inherits Application
    
    
        Private viewModel As MainWindowViewModel
    
        Private window As MainWindow
    
        Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)
    
            MyBase.OnStartup(e)
    
            window = New MainWindow
    
            viewModel = New MainWindowViewModel '1st instance of ProjectSearchViewModel created Here
    
            window.DataContext = viewModel
    
            window.Show() '2nd instance of ProjectSearchViewModel created Here
    
        End Sub
    
    End Class
    

    Partial Public Class App
    
        Inherits Application
    
    
        Private viewModel As MainWindowViewModel
    
        Private window As MainWindow
    
        Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)
    
            MyBase.OnStartup(e)
    
            window = New MainWindow
    
            viewModel = New MainWindowViewModel '1st instance of ProjectSearchViewModel created Here
    
            window.DataContext = viewModel
    
            window.Show() '2nd instance of ProjectSearchViewModel created Here
    
        End Sub
    
    End Class
    

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Cheminator"
        xmlns:vm="clr-namespace:Cheminator.ViewModel"
        xmlns:vw="clr-namespace:Cheminator.Views"
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:dxd="http://schemas.devexpress.com/winfx/2008/xaml/docking"
    xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
    xmlns:dxnb="http://schemas.devexpress.com/winfx/2008/xaml/navbar"
    xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
    xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
        Title="DXWpfApplication" Height="600" Width="800"
        dx:ThemeManager.ThemeName="Office2007Blue"
    >
    
    <Window.Resources>
        <ResourceDictionary Source="MainWindowResources.xaml" />
    </Window.Resources>
    
    <dxd:DockLayoutManager>
        <dxd:LayoutGroup>
            <dxd:LayoutGroup Orientation="Vertical"  Width="3*">
                <dxd:DocumentGroup Height="3*" SelectedTabIndex="0">
                    <dxd:DocumentPanel Caption="Document1" Height="3*" >
                         <ContentControl
                          Content="{Binding Path=ProjectsVM}"
                          />
                    </dxd:DocumentPanel>
                </dxd:DocumentGroup>
                <dxd:LayoutPanel Caption="Search Criteria" Height="*"  CaptionImage="Images/Icons/DetailView.png">                  
    
                    <ContentControl
                          Content="{Binding Path=ProjectsSearchVM}"
                          />
                </dxd:LayoutPanel>
            </dxd:LayoutGroup>
        </dxd:LayoutGroup>
    </dxd:DockLayoutManager>
    

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Cheminator"
    xmlns:vm="clr-namespace:Cheminator.ViewModel"
    xmlns:vw="clr-namespace:Cheminator.Views"    >
    
    <DataTemplate DataType="{x:Type vm:AllProjectsViewModel}">
        <vw:AllProjectsView />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type vm:ProjectSearchViewModel}">
        <vw:ProjectSearchView />
    </DataTemplate>
    

    <UserControl x:Class="Cheminator.Views.AllProjectsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
             xmlns:dxd="http://schemas.devexpress.com/winfx/2008/xaml/docking"
             xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"       
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:vm="clr-namespace:Cheminator.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    
        <dxg:GridControl AutoPopulateColumns="True" ShowBorder="False" >
            <dxg:GridControl.DataSource>
                <Binding Path="AllProjects"/>                     
            </dxg:GridControl.DataSource>
            <dxg:GridControl.View>
                <dxg:TableView>
    
            </dxg:TableView>
            </dxg:GridControl.View>
       </dxg:GridControl>
    </UserControl>
    

    <UserControl x:Class="Cheminator.Views.ProjectSearchView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:vm="clr-namespace:Cheminator.ViewModel"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="160" d:DesignWidth="470">
    <Grid Height="160" Width="470">
        <Grid.DataContext>
            <vm:ProjectSearchViewModel />
        </Grid.DataContext>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="175*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Label Content="Cotation ID:" Height="28" Margin="49,12,32,0" Name="Label1" VerticalAlignment="Top" />
        <TextBox Grid.Column="1" Height="23" Margin="0,14,159,0" Name="CotationIDTextBox" VerticalAlignment="Top" Text="{Binding Path=CotationID, UpdateSourceTrigger=LostFocus}"/>
    
        <Label Grid.Row="1" Content="Cotation Name:" Height="28" Margin="49,6,6,0" Name="Label2" VerticalAlignment="Top" />
        <TextBox Grid.Row="1" Grid.Column="1" Height="23" Margin="0,8,159,0" Name="CotationNameTextBox" VerticalAlignment="Top" Text="{Binding Path=ProjectSummary, UpdateSourceTrigger=PropertyChanged}"/>
    
            <Label Grid.Row="2" Content="User:" Height="28" Margin="49,6,32,0" Name="Label3" VerticalAlignment="Top" />
        <TextBox Grid.Row="2" Grid.Column="1" Height="23" Margin="0,8,159,0" Name="UserTextBox" VerticalAlignment="Top" Text="{Binding Path=UserName, UpdateSourceTrigger=PropertyChanged}"/>
        <Button 
                        Command="{Binding Path=LoadCommand}"
                        Content="_Load"
                        HorizontalAlignment="Right"
                        Margin="0,10,51,12" 
                        MinWidth="60" Grid.Row="3" Width="72" Grid.Column="1" />
    </Grid>
    </UserControl>
    

    Public Class MainWindowViewModel
        Inherits ViewModelBase
    
        Private _commands As ReadOnlyCollection(Of CommandViewModel)
        Private _ProjectsVM As AllProjectsViewModel
        Private _ProjectsSearchVM As ProjectSearchViewModel
    
        Public Sub New()
            MyBase.DisplayName = "Cheminator"
            _ProjectsSearchVM = New ProjectSearchViewModel
    
            Messenger.[Default].OfType(Of SearchResultMessage) _
                .Subscribe(Sub(param As SearchResultMessage)
                               ProjectsVM.AllProjects = ProjectsSearchVM.SearchResult
                           End Sub)
            _ProjectsVM = New AllProjectsViewModel
        End Sub
    
        Public ReadOnly Property ProjectsVM As AllProjectsViewModel
            Get
    
                If (_ProjectsVM IsNot Nothing) Then
                    Return _ProjectsVM
                End If
                Return Nothing
            End Get
        End Property
    
    
        Public ReadOnly Property ProjectsSearchVM As ProjectSearchViewModel
            Get
    
                If (_ProjectsSearchVM IsNot Nothing) Then
                    Return _ProjectsSearchVM
                End If
                Return Nothing
            End Get
        End Property
    
    End Class
    

    Public Class AllProjectsViewModel
        Inherits ViewModelBase
    
    
        Private m_ProjectsList As ObservableCollection(Of xGMV_Cotation)
    
    
        Public Sub New()
            MyBase.DisplayName = "Temp AllProjectsViewModel Name" 'Strings.AllProjectsViewModel_DisplayName
    
        End Sub
    
    
        Public Property AllProjects() As ObservableCollection(Of xGMV_Cotation)
            Get
                Return m_ProjectsList
            End Get
            Set(ByVal value As ObservableCollection(Of xGMV_Cotation))
                m_ProjectsList = value
                OnPropertyChanged("AllProjects")
            End Set
        End Property
    
    End Class
    

    结束班

1 个答案:

答案 0 :(得分:1)

每次创建ProjectSearchView用户控件时,您也会创建一个ProjectSearchViewModel。你应该从usercontrl xaml中删除以下内容。

<Grid.DataContext>
    <vm:ProjectSearchViewModel />
</Grid.DataContext>

因为你的datatemplate你不需要为ProjectSearchView设置datacontext,它已经有了正确的datacontext。