gpt4 book ai didi

wpf - Viewmodel 的多个实例

转载 作者:行者123 更新时间:2023-12-03 10:40:26 24 4
gpt4 key购买 nike

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

总体思路是这样的:

  • 搜索条件填写在 ProjectSearchView 中。
  • 当按下加载命令时,我使用响应式扩展方法发送 SearchResultMessage。
  • 消息被 MainWindowViewModel
  • 拾取
  • MainWindowViewModel 正在查询 ProjectSearchViewModel.SearchResult 并将 IObservable 列表分配给绑定(bind)到数据网格的 AllProjectsViewModel.AllProjects 以显示结果(AllProjectView 负责显示带有结果项目列表的网格)

  • 问题是 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


        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
    Public Class ProjectSearchViewModel
    Inherits ViewModelBase


    Private m_ProjectsList As ObservableCollection(Of xGMV_Cotation)

    Public Sub New()
    MyBase.DisplayName = "Cheminator.ProjectSearchViewModel"




    End Sub

    Dim _CotationID As Integer
    Public Property CotationID As Integer
    Get
    Return _CotationID
    End Get
    Set(ByVal value As Integer)
    _CotationID = value
    MyBase.OnPropertyChanged("CotationID")
    End Set
    End Property
    Public Property ProjectSummary As String
    Public Property UserName As String


    Private m_LoadCommand As RelayCommand
    Public ReadOnly Property LoadCommand As ICommand
    Get
    If m_LoadCommand Is Nothing Then
    Dim LoadAction As New Action(Of Object)(AddressOf Me.Load)
    m_LoadCommand = New RelayCommand(LoadAction)
    End If


    Return m_LoadCommand
    End Get
    End Property

    Public ReadOnly Property SearchResult() As ObservableCollection(Of xGMV_Cotation)
    Get

    Dim xWhere As String = ""
    Dim i As Integer = 0
    Dim parameterList As New ArrayList
    If Not String.IsNullOrEmpty(CotationID) Then
    xWhere = String.Format("CotationID = @{0}", i)
    parameterList.Add(CotationID)
    i += 1
    End If

    If Not String.IsNullOrEmpty(ProjectSummary) Then
    If i > 0 Then
    xWhere = xWhere & " AND "
    End If
    xWhere = xWhere & String.Format("ProjectSummary = '@{0}'", i)
    i += 1
    parameterList.Add(ProjectSummary)
    End If

    If Not String.IsNullOrEmpty(UserName) Then
    If i > 0 Then
    xWhere = xWhere & " AND "
    End If
    xWhere = xWhere & String.Format("UserName = '@{0}'", i)
    i += 1
    parameterList.Add(UserName)
    End If


    Return New ObservableCollection(Of xGMV_Cotation)(DataContext.DBEntities.xGMV_Cotations.Where(xWhere, parameterList.ToArray))
    End Get

    End Property

    Private Sub Load()


    OnPropertyChanged("SearchResult")
    Messenger.Default.Send(New SearchResultMessage())

    End Sub

    结束类

    最佳答案

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

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

    由于您的数据模板,您不需要为 ProjectSearchView 设置数据上下文,它已经具有正确的数据上下文。

    关于wpf - Viewmodel 的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5379998/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com