Проблема при загрузке выпадающего списка из набора данных VB. NET MvvM - PullRequest
0 голосов
/ 31 марта 2020

Попытка загрузить комбинированный список из базы данных с использованием набора данных; предметы не отображаются в выпадающем списке. Попытка сделать это без написания кода.

Модель:

Imports System.Data.OleDb

Public Class ChainModel
    Public Property ChainId As String
    Public Property ChainType As String

    Public Sub New(chainId As String, chainType As String)
        Me.ChainId = chainId
        Me.ChainType = chainType
    End Sub
End Class

Население набора данных:

Public Class DBCollection
    Public Shared dsChains As DataSet

    Public Shared Sub FillDataSet()
        Try
            dsChains = New DataSet()
            Dim adpt As OleDbDataAdapter = New OleDbDataAdapter With {
                .SelectCommand = New OleDbCommand("SELECT * FROM Chain ORDER BY Name, Manufacturer;", DbConn)
            }
            adpt.Fill(dsChains, Tbl)
            adpt.Dispose()
        Catch ex As Autodesk.AutoCAD.Runtime.Exception
            MsgBox("Unable to populate dataset! " & vbCrLf & ex.Message.ToString)
        End Try
    End Sub
End Class

Модель представления:

Public Class TTStraightViewModel
    Implements INotifyPropertyChanged
    Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Public Event PropertyChanged As PropertyChangedEventHandler Implements 
    INotifyPropertyChanged.PropertyChanged
    Dim _chainTypes As ObservableCollection(Of ChainModel) = New ObservableCollection(Of ChainModel)()

    Public Sub New()

    End Sub

    Public Property ChainTypes As ObservableCollection(Of ChainModel)
        Get
            If _chainTypes.Count = 0 Then DBLoadChains()
            Return _chainTypes
        End Get
        Set(value As ObservableCollection(Of ChainModel))
            _chainTypes = value
            NotifyPropertyChanged("ChainTypes")
        End Set
    End Property

    Private Sub DBLoadChains()
        For Each row As DataRow In DBCollection.dsChains.Tables("ChainTable").Rows
            Dim display As String = row("Name").ToString
            Dim value As String = row("id").ToString
            If display = String.Empty Then display = value
            _chainTypes.Add(New ChainModel(value, display))
        Next
    End Sub
End Class

XAML:

<Window x:Class="TtStraightView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace: LayoutTools" ResizeMode="NoResize" Width="Auto" 
xmlns:p="clr-namespace:LayoutTools.My" 
Title="Table Top Conveyor Straight" SizeToContent="WidthAndHeight" Height="Auto">

    <Window.DataContext>
        <local:TTStraightViewModel />
    </Window.DataContext>

    <Window.Resources>
        <p:MySettings x:Key="MySettings" />
    </Window.Resources>

    <StackPanel>
        <ComboBox Margin="0,3,0,3" Grid.Column="2" Grid.Row="1" Width="230" SelectedValuePath="ChainId" DisplayMemberPath="ChainType" ItemsSource="{Binding ChainTypes}"/>    
    </StackPanel>
</Window>

DBCollection.FillDataSet () вызывается во время запуска программы.

Работал с этим в течение нескольких дней, исследований, предыдущего кода и всего, и до сих пор не могу выяснить, почему в поле со списком не отображаются элементы при запуске кода. Есть идеи?

1 Ответ

0 голосов
/ 02 апреля 2020

Наконец-то разрешена моя неприятная ситуация, и для тех, кто работает в VB. NET, кто может быть удаленно заинтересован в том, как заполнить комбинированный список данными базы данных способом MvvM (без какого-либо кода), вот как я это сделал .

1) Создайте класс для эмуляции свойств таблицы базы данных по мере необходимости:

Public Class ChainModel
    Public Property ChainId As Integer

    Public Property ChainType As String

    Public Sub New(chainId As Integer, chainType As String)
        Me.ChainId = chainId
        Me.ChainType = chainType
    End Sub
End Class

2) Создайте класс базы данных для заполнения набора данных, который будет использоваться (обязательно иметь подключение к базе данных, настроенное до этого шага):

Public Class DBCollection
    Public Shared dsChains As DataSet
    Public Shared Sub FillDataSet()
        dsChains = New DataSet()
        Dim adpt As OleDbDataAdapter = New OleDbDataAdapter With {
            .SelectCommand = New OleDbCommand("SELECT id,Name FROM Chain ORDER BY Name, Manufacturer;", Cat.DbConn)
            }
        adpt.Fill(dsChains,"Chain")
        adpt.Dispose()
    End Sub
End Class

3) Настройте класс модели MvvM таким образом, чтобы набор данных заполнялся в конструкторе, а свойство наблюдаемой коллекции модели заполнялось непосредственно из набора данных:

Public Class TTStraightModel
    Dim _chainType As String = My.Settings.TTStraightChainType
    Dim _chainTypeList As ObservableCollection(Of ChainModel)

    Public Sub New()
        DBCollection.FillDataSet()
    End Sub

    Public Property ChainType As String
        Get
            Return _chainType
        End Get
        Set(value As String)
            _chainType = value
            My.Settings.TTStraightChainType = _chainType
        End Set
    End Property

    Public Property ChainTypeList As ObservableCollection(Of ChainModel)
        Get
            _chainTypeList = New ObservableCollection(Of ChainModel)()
            For Each row As DataRow In DBCollection.dsChains.Tables("Chain").Rows
                Dim display As String = row("Name").ToString
                Dim value As String = row("id").ToString
                If display = String.Empty Then display = value
                _chainTypeList.Add(New ChainModel(value, display))
            Next
            Return _chainTypeList
        End Get
        Set(value As ObservableCollection(Of ChainModel))
            _chainTypeList = value
        End Set
    End Property
End Class

4) Настройте модель представления MvvM таким образом, чтобы она считывала свойство наблюдаемой коллекции модели в собственное свойство наблюдаемой коллекции:

Public Class TTStraightViewModel
    Implements INotifyPropertyChanged
    Private Sub NotifyPropertyChanged(Optional propertyName As String = "")
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub
    Public Event PropertyChanged As PropertyChangedEventHandler Implements 
INotifyPropertyChanged.PropertyChanged

    ReadOnly _ttStraightModel As New TTStraightModel()

    Public Sub New()
    End Sub

    Public Property ChainType As String
        Get
            Return _ttStraightModel.ChainType
        End Get
        Set(value As String)
            _ttStraightModel.ChainType = value
            NotifyPropertyChanged("ChainType")
        End Set
    End Property

    Public Property ChainTypeList As ObservableCollection(Of ChainModel)
        Get
            Return _ttStraightModel.ChainTypeList
        End Get
        Set(value As ObservableCollection(Of ChainModel))
            _ttStraightModel.ChainTypeList = value
            NotifyPropertyChanged("ChainTypeList")
        End Set
    End Property
End Class

5) Наконец, установите до представления XAML MvvM, так что выпадающий список связывается непосредственно с экспонируемым свойством модели представления (предварительно настроив представление). модель как контекст данных для представления):

<Window x:Class="TtStraightView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CatScriptLayoutTools" ResizeMode="NoResize" Width="Auto" 
    xmlns:p="clr-namespace:CatScriptLayoutTools.My" 
    Title="Table Top Conveyor Straight" SizeToContent="WidthAndHeight" Height="Auto">

    <Window.DataContext>
        <local:TTStraightViewModel />
    </Window.DataContext>

    <Window.Resources>
        <p:MySettings x:Key="MySettings" />
    </Window.Resources>

    <StackPanel>
        <ComboBox Margin="0,3,0,3" Width="230" SelectedValuePath="ChainId" DisplayMemberPath="ChainType" ItemsSource="{Binding ChainTypeList}" SelectedItem="{Binding ChainType}"/>    
</StackPanel>
</Window>

SelectedValuePath = "ChainId" DisplayMemberPath = "ChainType" гарантирует, что правильная комбинация идентификатора / значения связана с выпадающим списком.

...