【问题标题】:WPF Databinding with ObservableCollection使用 ObservableCollection 进行 WPF 数据绑定
【发布时间】:2011-06-16 05:30:06
【问题描述】:

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

当我单击 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

结束类

公共类 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

结束类

【问题讨论】:

    标签: wpf binding observablecollection inotifypropertychanged


    【解决方案1】:

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

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

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

    <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
    

    【讨论】:

      【解决方案2】:

      您可能想要做的是将您的 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>
      

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

      【讨论】:

      • 列表框项是十进制值,我希望标签是列表框中值的总和。
      • 对不起,错过了那部分。总和将是棘手的部分。因为双打没有改变事件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2019-11-26
      • 2011-06-06
      • 2011-03-21
      相关资源
      最近更新 更多