WPF数据绑定与ObservableCollection

时间:2011-01-26 23:26:36

标签: wpf binding observablecollection inotifypropertychanged

在WPF窗口中,我有一个简单的十进制值列表框,其中包含与其绑定的Amounts的ObservableCollection,一个绑定到Total属性的标签,该属性显示ListBox下面的值的总和,以及一个TextBox输出到ListBox右侧绑定到selectedItem.Amount属性。

当我点击ListBox中的某个项目时,我希望能够在填充的文本框中编辑selectedItem的值,选中TextBox,并让listBoxItem更新其值,我希望更新总和标签也是如此。

我理解元素到元素的数据绑定是如何工作的(即ListBox到Textbox) 我弄清楚的是元素到对象的数据绑定(即ListBox / ObservableCollection到Total属性)

非常感谢!

以下是我到目前为止的两个简单类:

Public Class TransactionModel
Implements INotifyPropertyChanged
'Public Property Amount As Decimal
Private _amount As Decimal
Public Property Amount As Decimal
    Get
        Return _amount
    End Get
    Set(ByVal value As Decimal)
        _amount = value
        OnPropertyChanged(New PropertyChangedEventArgs("Amount"))
    End Set
End Property

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)
    If Not e Is Nothing Then
        RaiseEvent PropertyChanged(Me, e)
    End If
End Sub

结束班

Public Class ViewModel     实现INotifyPropertyChanged

Private oc As ObservableCollection(Of TransactionModel)
Sub New()
    oc = New ObservableCollection(Of TransactionModel)
    oc.Add(New TransactionModel With {.Amount = 10.0})
    oc.Add(New TransactionModel With {.Amount = 20.0})
    oc.Add(New TransactionModel With {.Amount = 30.0})
    oc.Add(New TransactionModel With {.Amount = 40.0})
End Sub

Public Function GetAmounts() As ObservableCollection(Of TransactionModel)
    Return oc
End Function

Private _total As Decimal = 0.0
Public Property Total As Decimal
    Get
        For Each o In oc
            _total += o.Amount
        Next
        Return _total
    End Get
    Set(ByVal value As Decimal)
        _total = value
        OnPropertyChanged(New PropertyChangedEventArgs("Total"))
    End Set
End Property

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs)
    If Not e Is Nothing Then
        RaiseEvent PropertyChanged(Me, e)
    End If
End Sub

结束班

2 个答案:

答案 0 :(得分:2)

第一部分是添加一个TextBox,并将其绑定到ListBox上的SelectedItem属性。这将导致TextBox显示所选项目的金额,并允许用户更新其值:

 <TextBox DataContext="{Binding ElementName=lb1, Path=SelectedItem}"
    Text="{Binding Path=Amount}" />

然后,您需要一个名为TotalAmount的ViewModel上的属性,以及一个绑定到它的值的TextBlock。您还必须为“值”处理PropertyChanged并重新引发“TotalAmount”事件,这将导致视图刷新:

<TextBlock Text="{Binding Path=TotalAmount}"></TextBlock>

和事件处理程序:

Public Class ViewModel Implements INotifyPropertyChanged
    ...
    Public Sub New()
        items = New ObservableCollection(Of TransactionModel)()
        Dim tm As New TransactionModel()
        tm.PropertyChanged += New PropertyChangedEventHandler(TransactionModel_PropertyChanged)
        items.Add(tm)
        tm = New TransactionModel()
        tm.PropertyChanged += New PropertyChangedEventHandler(TransactionModel_PropertyChanged)
        items.Add(tm)
        tm = New TransactionModel()
        tm.PropertyChanged += New PropertyChangedEventHandler(TransactionModel_PropertyChanged)
        items.Add(tm)
    End Sub

    Private Sub TransactionModel_PropertyChanged(sender As Object, e As PropertyChangedEventArgs)
        If e.PropertyName = "Amount" Then
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("TotalAmount"))
        End If
    End Sub
    ...
End Class

答案 1 :(得分:0)

您可能想要做的是将TextBox和标签绑定到ListBox的SelectedItem属性

这里有一些XAML向您展示我的意思....

<StackPanel>
    <TextBlock Width="248" Height="24" Text="Colors:" TextWrapping="Wrap"/>
    <ListBox x:Name="lbColor" Width="248" Height="56">
        <ListBoxItem Content="Blue"/>
        <ListBoxItem Content="Green"/>
        <ListBoxItem Content="Yellow"/>
        <ListBoxItem Content="Red"/>
        <ListBoxItem Content="Purple"/>
        <ListBoxItem Content="Orange"/>
    </ListBox>
    <TextBlock Width="248" Height="24" Text="You selected color:" />
    <TextBlock Width="248" Height="24" Text={Binding ElementName="lbColor"}/>
</StackPanel>

要使您的标签成为值的总和,您可以使用转换器并直接绑定到集合。