【问题标题】:DevExpress GridControl Bound to Object with a BindingList isn't updating controls使用 BindingList 绑定到对象的 DevExpress GridControl 不更新控件
【发布时间】:2019-04-04 01:27:22
【问题描述】:

我有一个带有几个控件的表单;一些文本框数据绑定到私有表单对象的属性(财务)和 DevExpress GridControl,数据绑定到同一财务对象上的 BindingList(of Fee) (Fees) 属性。 Financial 的属性之一是只读属性,它根据 Financial and Fees (MonthlyCosts) 的其他属性计算一些数据。 Financial 和 Fee 都实现了 INotifyPropertyChanged。

我遇到的问题是,当对 GridControl 进行更改时,绑定到该 MonthlyCosts 属性的文本框不会更新。如果我更改 GridControl 中的费用成本,然后更改也用于该计算的文本框值(Margin),则具有计算值的文本框只会在我更改 Margin 后更新。

部分相关代码如下所示:

Public Class Financial
    Inherits BindableBase ' helper for INotifyPropertyChanged

    Public Property Margin As Decimal
        Get
            return _margin
        End Get
        Set
            SetProperty() ' INotifyPropertyChanged stuff
        End Set
    End Property

    Public ReadOnly Property Fees As BindingList(Of Fee)

    Public ReadOnly Property Total as Decimal
        Get
            return Fees.Sum(Function(fee) fee.Amount) / (1 - Margin)
        End Get
    End Property
End Class

Public Class Fee
    Inherits BindableBase ' helper for INotifyPropertyChanged

    Public Property Amount as Decimal
End Class

形式:

' Setup the databindings
Margin.DataBindings.Add("EditValue", Financial, NameOf(Financial.Margin))
FeeGrid.DataBindings.Add("DataSource", Financial, NameOf(Financial.Fees))
Total.DataBindings.Add("EditValue", Financial, NameOf(Financial.Total))

数据绑定似乎都可以正常工作,除非更改费用不会更改总计文本框。如果我在 MessageBox 中放置一个弹出 Total 属性的按钮,它会报告正确的 Total,但文本框没有更新。似乎费用对象上的 NotifyPropertyChanged 没有通过 BindingList 向上传播到 Form 以告诉它刷新 Total 文本框。

【问题讨论】:

  • 您显示了Public Class Fee 的声明并且还有Public ReadOnly Property Fees As BindingList(Of Fees) - 这是帖子中的拼写错误吗?
  • 是的,这只是一个错字。谢谢!

标签: .net vb.net winforms data-binding devexpress-windows-ui


【解决方案1】:

数据绑定似乎都可以正常工作,除了在更改费用的情况下不会更改总计文本框。

您的代码中没有显示任何会引发属性 Total 的 PropertyChanged 事件。由于Total 是一个取决于属性FeesMargin 的计算值,因此对这些属性的更改也应该引发Total 的更改通知。

由于Fees 被声明为BindingList(Of Fee),订阅其ListChanged Event 将提供一种通知Total 更改的方法,因为Fees 发生更改。

以下是与您发布的内容类似的有效 WinForm 示例,但它仅使用常用控件(TextBox、DataGridView 和 Label)。

Public Class BindableBase : Implements INotifyPropertyChanged
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Protected Sub RaisePropertyChanged(<CallerMemberName> Optional PropName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropName))
    End Sub
End Class

Public Class Financial : Inherits BindableBase

    Public _margin As Decimal

    Public Sub New()
        Fees = New BindingList(Of Fee)
        AddHandler Fees.ListChanged, AddressOf Fees_Changed
    End Sub

    Private Sub Fees_Changed(sender As Object, e As ListChangedEventArgs)
        NotifyTotalChanged()
    End Sub

    Private Sub NotifyTotalChanged()
        RaisePropertyChanged(NameOf(Me.Total))
    End Sub

    Public Property Margin As Decimal
        Get
            Return _margin
        End Get
        Set(ByVal value As Decimal)
            If value <> _margin Then
                _margin = value
                RaisePropertyChanged()
                NotifyTotalChanged() ' Margin affects Total
            End If
        End Set
    End Property

    Public ReadOnly Property Fees As BindingList(Of Fee)

    Public ReadOnly Property Total As Decimal
        Get
            Return Fees.Sum(Function(fee) fee.Amount) / (1 - Margin)
        End Get
    End Property

End Class

Public Class Fee : Inherits BindableBase

    Private _Amount As Decimal
    Public Property Amount As Decimal
        Get
            Return _Amount
        End Get
        Set(value As Decimal)
            If value <> _Amount Then
                _Amount = value
                RaisePropertyChanged()
            End If
        End Set
    End Property
End Class

示例用法:

Public Class Form1
    Private Financial As New Financial
    Protected Overrides Sub OnLoad(e As EventArgs)
        MyBase.OnLoad(e)
        SetFinancialBindings()
    End Sub

    Private Sub SetFinancialBindings()
        Margin.DataBindings.Add("Text", Me.Financial, NameOf(Me.Margin))
        FeeGrid.DataBindings.Add("DataSource", Me.Financial, NameOf(Me.Financial.Fees))
        Total.DataBindings.Add("Text", Me.Financial, NameOf(Me.Financial.Total))
    End Sub
End Class

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多