Vb.net MVVM与设计时数据的绑定在设计时正常工作,但在运行时不能正常工作
我有一个简单的MVVM项目,其中包含设计时数据,可以很好地处理主数据和一个列表框,每个子项都有用户控件。 但是,当我在运行时实例化这些类时,主数据会显示,而子数据不会显示(但是列表框的项目数正确,但是文本框中不会显示任何数据) 我注意到Sport上的构造函数被调用的次数远远超过我预期的次数(例如,在运行时,我预期它只被调用两次,但调用次数似乎不止这些) 我有班上的人,还有运动。每个人都可以喜欢多种运动,并拥有自己喜欢的球队。 我有一个personViewModel和sportViewModel,它继承自viewModelBase 这是我的VB.net代码Vb.net MVVM与设计时数据的绑定在设计时正常工作,但在运行时不能正常工作,vb.net,mvvm,Vb.net,Mvvm,我有一个简单的MVVM项目,其中包含设计时数据,可以很好地处理主数据和一个列表框,每个子项都有用户控件。 但是,当我在运行时实例化这些类时,主数据会显示,而子数据不会显示(但是列表框的项目数正确,但是文本框中不会显示任何数据) 我注意到Sport上的构造函数被调用的次数远远超过我预期的次数(例如,在运行时,我预期它只被调用两次,但调用次数似乎不止这些) 我有班上的人,还有运动。每个人都可以喜欢多种运动,并拥有自己喜欢的球队。 我有一个personViewModel和sportViewModel,
Imports System.Collections.ObjectModel
Public Class Person
Public Property Forename As String
Public Property Surname As String
Public Sports As New ObservableCollection(Of Sport)
End Class
Public Class Sport
Public Sub New()
Debug.WriteLine("test")
End Sub
Public Property SportName As String
Public Property FavouriteProfessionalTeam As String
End Class
Imports System.Collections.ObjectModel
Namespace ViewModel
Public Class PersonViewModel
Inherits ViewModel.ViewModelBase
Public Property Person1 As Person
Public Property SportViewModels As New ObservableCollection(Of SportViewModel)
Public Sub New()
LoadData()
End Sub
''' <summary>
''' Loads the data for the application.
''' </summary>
Private Sub LoadData()
If IsInDesignModeStatic Then
LoadDesignData()
Else
End If
End Sub
''' <summary>
''' Loads temporary data for use in the designer.
''' </summary>
Private Sub LoadDesignData()
Person1 = New Person
Person1.Forename = "Mickey Run Time"
Person1.Surname = "Mouse Run Time"
Person1.Sports.Add(New Sport With {.FavouriteProfessionalTeam = "Man Utd", .SportName = "Soccer"})
Person1.Sports.Add(New Sport With {.FavouriteProfessionalTeam = "Barcelona", .SportName = "Spanish Soccer"})
Person1.Sports.Add(New Sport With {.FavouriteProfessionalTeam = "Ulster", .SportName = "Rugby"})
For Each sport1 In Person1.Sports
Dim sportVm As New SportViewModel With {.Sport1 = sport1}
SportViewModels.Add(sportVm)
Next
End Sub
End Class
End Namespace
Namespace ViewModel
Public Class SportViewModel
Inherits ViewModel.ViewModelBase
Public Property Sport1 As New Sport
Public Property Person1 As Person
Public Sub New()
LoadData()
End Sub
''' <summary>
''' Loads the data for the application.
''' </summary>
Private Sub LoadData()
If IsInDesignModeStatic Then
LoadDesignData()
Else
' Debug.WriteLine(Sport1.SportName)
' Load the student data asynchronously
'StudentContextInstance = New StudentContext
'Dim loadop =
' StudentContextInstance.Load(StudentContextInstance.
' GetStudentsQuery(),
' AddressOf OnStudentsLoaded, Nothing)
End If
End Sub
''' <summary>
''' Loads temporary data for use in the designer.
''' </summary>
Private Sub LoadDesignData()
Sport1 = New Sport With {.SportName = "Design Time Name", .FavouriteProfessionalTeam = "Design Time Team"}
End Sub
End Class
End Namespace
Imports System.ComponentModel
Namespace ViewModel
Public Class ViewModelBase
Implements INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Private Shared _isInDesignMode As Boolean?
Public Shared ReadOnly Property IsInDesignModeStatic As Boolean
Get
If Not _IsInDesignMode.HasValue Then
_IsInDesignMode = DesignerProperties.GetIsInDesignMode(New DependencyObject)
End If
Return _IsInDesignMode.Value
End Get
End Property
Protected Sub OnPropertyChanged(ByVal propertyName As String)
' Send an event notification that the property changed
' This allows the UI to know when one of the items changes
If Not String.IsNullOrEmpty(propertyName) Then
RaiseEvent PropertyChanged(Me,
New PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
End Namespace
这是XAML代码
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModel="clr-namespace:WpfApplicationMVVMTest.ViewModel"
xmlns:View="clr-namespace:WpfApplicationMVVMTest" mc:Ignorable="d" x:Class="PersonWindow"
Title="PersonWindow" Height="1114.8" Width="542">
<Window.Resources></Window.Resources>
<Window.DataContext>
<ViewModel:PersonViewModel />
</Window.DataContext>
<Grid>
<Grid x:Name="Grid1" HorizontalAlignment="Left" Margin="41,39,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Forename:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="ForenameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Person1.Forename, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Surname:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox x:Name="SurnameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Person1.Surname, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
</Grid>
<ListBox Margin="41,108,59,753" ItemsSource="{Binding Path=SportViewModels}" >
<ListBox.ItemTemplate>
<DataTemplate>
<View:SportUserControl DataContext="{Binding}" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
<UserControl
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModel="clr-namespace:WpfApplicationMVVMTest.ViewModel" x:Class="SportUserControl"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="600">
<UserControl.Resources></UserControl.Resources>
<UserControl.DataContext>
<ViewModel:SportViewModel />
</UserControl.DataContext>
<Grid>
<Grid x:Name="Grid1" HorizontalAlignment="Left" Margin="31,26,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Favourite Professional Team:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="FavouriteProfessionalTeamTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Sport1.FavouriteProfessionalTeam, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Sport Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox x:Name="SportNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Sport1.SportName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
</Grid>
</Grid>
</UserControl>
这是我的设计时间图像,显示了3项运动(根据我的负载设计时间数据)。
这是我的运行时窗口,显示了两个运动(尽管它们没有数据,这就是问题所在)。
您正在标记和代码中设置DataContext…删除标记并坚持一种模式
非常感谢,请更全面地解释我在您的评论之后所做的事情:我在SportsView用户控件中注释了这段代码,也是为了确认这样做的副作用。SportView不再单独显示设计时数据。但是,当设计时数据显示在PersonView列表框上时,它确实会显示设计时数据。刚刚找到一种方法,这样它甚至可以用于子视图,可以使用d:DataContext,以便仅在设计时设置:d:DataContext=“{d:DesignInstance Type=vm:ViewModalThatYouWantToUse,IsDesignTimeCreatable=True}”
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModel="clr-namespace:WpfApplicationMVVMTest.ViewModel"
xmlns:View="clr-namespace:WpfApplicationMVVMTest" mc:Ignorable="d" x:Class="PersonWindow"
Title="PersonWindow" Height="1114.8" Width="542">
<Window.Resources></Window.Resources>
<Window.DataContext>
<ViewModel:PersonViewModel />
</Window.DataContext>
<Grid>
<Grid x:Name="Grid1" HorizontalAlignment="Left" Margin="41,39,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Forename:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="ForenameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Person1.Forename, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Surname:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox x:Name="SurnameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Person1.Surname, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
</Grid>
<ListBox Margin="41,108,59,753" ItemsSource="{Binding Path=SportViewModels}" >
<ListBox.ItemTemplate>
<DataTemplate>
<View:SportUserControl DataContext="{Binding}" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
<UserControl
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModel="clr-namespace:WpfApplicationMVVMTest.ViewModel" x:Class="SportUserControl"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="600">
<UserControl.Resources></UserControl.Resources>
<UserControl.DataContext>
<ViewModel:SportViewModel />
</UserControl.DataContext>
<Grid>
<Grid x:Name="Grid1" HorizontalAlignment="Left" Margin="31,26,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Favourite Professional Team:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="FavouriteProfessionalTeamTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Sport1.FavouriteProfessionalTeam, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Sport Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox x:Name="SportNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Sport1.SportName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
</Grid>
</Grid>
</UserControl>