4

私は、メイン データと各子項目のユーザー コントロールを持つリスト ボックスの両方で正常に動作する設計時データを含む単純な MVVM プロジェクトを持っています。ただし、実行時にクラスをインスタンス化すると、マスター データは表示されますが、子データは表示されません (ただし、リスト ボックスには正しい数の項目がありますが、テキスト ボックスに表示されるデータはありません)。

Sport のコンストラクターが、私が予想していたよりもはるかに多く呼び出されることに気付きました (たとえば、実行時に呼び出されるのは 2 回だけだと思いますが、それ以上に呼び出されるようです)。

クラス Person と Sport があります。誰もが複数のスポーツを好きになり、お気に入りのチームを持つことができます。viewModelBase から継承する personViewModel と sportViewModel があります。

ここに私のVB.netコードがあります

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

これは、表示用に MVVM をセットアップする私のウェイン ウィンドウのコード ビハインドです。 Imports System.Collections.ObjectModel Imports WpfApplicationMVVMTest.ViewModel

Class MainWindow
    Public Property Person1 As Person
    Public Property SportViewModels As New ObservableCollection(Of SportViewModel)
    Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
        Dim wndPerson As New PersonWindow


        Person1 = New Person
        Person1.Forename = "Donald"
        Person1.Surname = "Duck"

        Person1.Sports.Add(New Sport With {.FavouriteProfessionalTeam = "Man Utd", .SportName = "Soccer"})
        Person1.Sports.Add(New Sport With {.FavouriteProfessionalTeam = "Barcelona", .SportName = "Spanish Soccer"})

        For Each sport1 In Person1.Sports
            Dim sportVm As New SportViewModel With {.Sport1 = sport1}
            SportViewModels.Add(sportVm)
        Next




        Dim vm As New ViewModel.PersonViewModel
        vm.SportViewModels = SportViewModels
        vm.Person1 = Person1
        wndPerson.DataContext = vm
        wndPerson.Show()
    End Sub
End Class

ここに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つのスポーツが表示された私の設計時の画像です(ロード設計時のデータに従って)。 ここに画像の説明を入力

これは、2 つのスポーツが表示されている実行時間ウィンドウです (データがありませんが、これが問題です)。 ここに画像の説明を入力

4

1 に答える 1

2

マークアップとコードでデータコンテキストを設定しています...マークアップを削除して1つのパターンに固執します

于 2013-01-09T14:33:27.713 に答える