VB Net ObservableCollection未正确更新ListView

时间:2016-01-02 00:36:03

标签: wpf vb.net listview

`只是学习WPF,所以更新旧的但有用的程序。我把编程作为一种爱好。我做的大部分学习都来自互联网,我已经搜索了几天的答案,非常感谢任何帮助。

我正在使用一个observablecollection来查看它是如何工作的。我的问题是observablecollection绑定的列表视图不显示正确的数据。我在调试中添加了一个消息框。在我这样做之后,它完美地工作,尽管我每次都必须打得好。经过广泛阅读后,我希望listview能够在每次添加时更新(没有addrange方法),但它所做的只是显示正确的条目数,但每一行都包含最后一次添加。

我已经多次更改了XAML并且代码背后但似乎无法理解我做错了什么,或者更重要的是为什么它与MsgBox一起工作。下面的代码是所有更改的最终版本,不是那么漂亮!

'convert from datatable to observable collection
    For x1 = 0 To DBdtPW.Rows.Count - 1
        PWResultHolder.PWNominalDia = DBdtPW.Rows(x1).Item(0)
        PWResultHolder.PWInternalDia = DBdtPW.Rows(x1).Item(1).ToString
        PWResultHolder.PWInternalArea = DBdtPW.Rows(x1).Item(2).ToString
        PWResultHolder.PWWithin = DBdtPW.Rows(x1).Item(3).ToString
        PWResultHolder.PWVelocity = DBdtPW.Rows(x1).Item(4).ToString
        PWResultHolder.PWPressureDropPM = DBdtPW.Rows(x1).Item(5).ToString
        PWResults.Add(PWResultHolder)
        'MsgBox(PWResultHolder.PWNominalDiaValue, MsgBoxStyle.OkOnly, "Invalid Input")
    Next

再次感谢您的帮助。

Public Class clsPWSizing

Implements INotifyPropertyChanged

Public PWPipeType As String 'Pipework material
Public PWPipeTypeList As New ObservableCollection(Of String) 'For populating pipe type combo box
Public PWFluidTemperatureList As New ObservableCollection(Of String) 'For populating temperature combo box
Public PWGlycolPerCentList As New ObservableCollection(Of String) 'For populating glycol combo box
Public PWResults As New ObservableCollection(Of clsPWFluidResult) 'For populating result listview
Public PWMinVelvalue As String 'Pipework minimum velocity
Public PWMaxVelvalue As String 'Pipework maximum velocity
Public PWMinPDvalue As String 'Pipework minimum pressure drop
Public PWMaxPDvalue As String 'Pipework maximum pressure drop
Public PWFluidTemperature As String ' Fluid temperature in the pipe
Public PWGlycolPerCent As String 'Percentage of glycol in fluid
Public PWDensity As String 'Density of fluid
Public PWDynVisc As String 'Dynamic viscosity of fluid
Public PWMassFlowRateValue As String 'Mass flow rate of fluid
Public GrdPWSizingVisible As System.Windows.Visibility 'Is the grid visible?

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

    Public Property PWResultListView()
    Get
        Return PWResults
    End Get
    Set(ByVal value)
        PWResults = value
    End Set
End Property
 <ListView x:Name="lstVwPWResults" HorizontalAlignment="Left" Height="405" Margin="612,53,0,0" VerticalAlignment="Top" Width="637" ItemsSource="{Binding PWResultListView, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="100" 
                            Header="Nom Dia" 
                            DisplayMemberBinding="{Binding PWNominalDia}"/>
                    <GridViewColumn Width="100" 
                            Header="Int Dia" 
                            DisplayMemberBinding="{Binding PWInternalDia}"/>
                    <GridViewColumn Width="100" 
                            Header="Area" 
                            DisplayMemberBinding="{Binding PWInternalArea}"/>
                    <GridViewColumn Width="100" 
                            Header="Within" 
                            DisplayMemberBinding="{Binding PWWithin}"/>
                    <GridViewColumn Width="100" 
                            Header="Velocity" 
                            DisplayMemberBinding="{Binding PWVelocity}"/>
                    <GridViewColumn Width="100" 
                            Header="Pressure Drop" 
                            DisplayMemberBinding="{Binding PWPressureDropPM}"/>
                </GridView>
            </ListView.View>
        </ListView>

2 个答案:

答案 0 :(得分:1)

你的代码仍然错过了重现问题的必要部分,但是好吧,我猜。我删除了所有非必要部分,并添加了伪方法来填充ObservableCollection。

ObservableCollection的项目类

Public Class clsPWFluidResult
    Public Property PWNominalDia As String
    Public Property PWInternalDia As String
    Public Property PWInternalArea As String
    Public Property PWWithin As String
    Public Property PWVelocity As String
    Public Property PWPressureDropPM As String
End Class

拥有ObservableCollection的ViewModel类。

Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Public Class clsPWSizing
    Implements INotifyPropertyChanged

    Public PWResults As New ObservableCollection(Of clsPWFluidResult) 'For populating result listview

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    Public Property PWResultListView()
        Get
            Return PWResults
        End Get
        Set(ByVal value)
            PWResults = value
        End Set
    End Property

    Public Sub Pupulate()
        For Each indexString In Enumerable.Range(0, 10).Select(Function(x) x.ToString())
            Dim PWResultHolder As New clsPWFluidResult()

            PWResultHolder.PWNominalDia = "NominalDia" & indexString
            PWResultHolder.PWInternalDia = "InternalDia" & indexString
            PWResultHolder.PWInternalArea = "InternalArea" & indexString
            PWResultHolder.PWWithin = "Within" & indexString
            PWResultHolder.PWVelocity = "Velocity" & indexString
            PWResultHolder.PWPressureDropPM = "PressureDropPM" & indexString

            PWResults.Add(PWResultHolder)
        Next
    End Sub
End Class

View的代码(MainWindow.xaml.vb)

Class MainWindow
    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Dim vm = New clsPWSizing()
        Me.DataContext = vm
        vm.Pupulate()
    End Sub
End Class

XAML of View(MainWindow.xaml)

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="500"
        Loaded="Window_Loaded">
    <Grid>
        <ListView ItemsSource="{Binding PWResultListView}">
            <ListView.View>
                <GridView >
                    <GridViewColumn Width="100"
                            Header="Nom Dia" 
                            DisplayMemberBinding="{Binding PWNominalDia}"/>
                    <GridViewColumn Width="100" 
                            Header="Int Dia" 
                            DisplayMemberBinding="{Binding PWInternalDia}"/>
                    <GridViewColumn Width="100" 
                            Header="Area" 
                            DisplayMemberBinding="{Binding PWInternalArea}"/>
                    <GridViewColumn Width="100" 
                            Header="Within" 
                            DisplayMemberBinding="{Binding PWWithin}"/>
                    <GridViewColumn Width="100" 
                            Header="Velocity" 
                            DisplayMemberBinding="{Binding PWVelocity}"/>
                    <GridViewColumn Width="100" 
                            Header="Pressure Drop" 
                            DisplayMemberBinding="{Binding PWPressureDropPM}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

此代码按预期工作。所以在你没有发布的地方应该有一个问题。请检查此代码与实际代码之间的差异,以缩小问题的原因。

答案 1 :(得分:0)

如果您正在使用ViewModel(MVVM),请实现INotifyPropertyChanged

使用此

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string property)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(property));
}

在Collection的(ListView的ItemSource)Setter中,执行此操作

private ObservableCollection<someType> _pWResults;
public ObservableCollection<someType> PWResults
{
   get{ return _pWResults }
   set
   {
      _pWResults = value;
       OnPropertyChanged("PWResults");
   }
 }

很抱歉在c#中提供了例如代码