2014-01-06 89 views
0

我遇到了带有数据绑定文本值更新标签的问题。我有一个能够计算出运动员最佳投掷数的类别,并且这种类型必须以我的形式出现在标签上。类是如下VB.NET Databound标签不更新

Imports System.ComponentModel 
Imports System.Runtime.CompilerServices 

Public Class Competition 
    Public Sub New() 
     Competitors = New List(Of Competitor)() 
    End Sub 
    Public Property Competitors() As List(Of Competitor) 
     Get 
      Return m_Competitors 
     End Get 
     Set(value As List(Of Competitor)) 
      m_Competitors = value 
     End Set 
    End Property 
    Private m_Competitors As List(Of Competitor) 
    Public ReadOnly Property CurrentPlacings() As List(Of Competitor) 
     Get 
      Return Competitors.OrderByDescending(Function(c) c.BestThrow).ToList() 

     End Get 
    End Property 

End Class 
Public Class Competitor 
    Implements System.ComponentModel.INotifyPropertyChanged 
    Public Event PropertyChanged(sender As Object, 
      e As System.ComponentModel.PropertyChangedEventArgs) _ 
      Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged 
    Public Sub New() 
     Throws = New List(Of [Throw])() 
    End Sub 
    Public Property FirstName() As String 
     Get 
      Return m_FirstName 
     End Get 
     Set(value As String) 
      m_FirstName = value 
     End Set 
    End Property 
    Private m_FirstName As String 
    Public Property LastName() As String 
     Get 
      Return m_LastName 
     End Get 
     Set(value As String) 
      m_LastName = value 
     End Set 
    End Property 
    Private m_LastName As String 
    Public Property compNumber() As String 
     Get 
      Return m_compNumb 
     End Get 
     Set(value As String) 
      m_compNumb = value 
     End Set 
    End Property 
    Private m_compNumb As String 
    Public Property club() As String 
     Get 
      Return m_club 
     End Get 
     Set(value As String) 
      m_club = value 
     End Set 
    End Property 
    Private m_club As String 
    Public Property Throws() As List(Of [Throw]) 
     Get 
      Return m_Throws 
     End Get 
     Set(value As List(Of [Throw])) 
      m_Throws = value 
     End Set 
    End Property 
    Private m_Throws As List(Of [Throw]) 
    Public ReadOnly Property BestThrow() As Object 
     Get 
      Dim bt = Throws.Where(Function(t) t.Status = ThrowStatus.Valid).OrderByDescending(Function(t) t.Distance).First() 
      If (IsNothing(bt.Distance)) Then 
       bt.Distance = "0" 
      End If 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("BestThrow")) 
      Return bt 

     End Get 
    End Property 
    Public ReadOnly Property getLabel 
     Get 
      Return compNumber & " " & LastName & ", " & FirstName & vbCrLf & club 
     End Get 
    End Property 

End Class 
Public Enum ThrowStatus 
    Valid 
    Pass 
    Foul 
End Enum 
Public Class [Throw] 
    Implements INotifyPropertyChanged 
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    Public Property Status() As ThrowStatus 
     Get 
      Return m_Status 
     End Get 
     Set(value As ThrowStatus) 
      m_Status = value 
     End Set 
    End Property 
    Private m_Status As ThrowStatus 
    Public Property Distance() As String 
     Get 
      If Status = ThrowStatus.Valid Then 
       If (m_Distance > 0) Then 
        Return m_Distance 
       Else 
        Return Nothing 
       End If 

      ElseIf Status = ThrowStatus.Pass Then 
       Return "PASS" 
      ElseIf Status = ThrowStatus.Foul Then 
       Return "FOUL" 
      Else 
       Return Nothing 
      End If 

     End Get 
     Set(value As String) 
      If (value > 0) Then 


       If (IsNumeric(value)) Then 
        m_Distance = value 
        Status = ThrowStatus.Valid 
       ElseIf (value = "foul") Then 
        Status = ThrowStatus.Foul 
       ElseIf (value = "pass") Then 
        Status = ThrowStatus.Pass 
       Else 
        Status = ThrowStatus.Valid 
        m_Distance = Nothing 
       End If 
      Else 
       m_Distance = Nothing 
       Status = ThrowStatus.Valid 
      End If 
      OnPropertyChanged("Distance") 
     End Set 
    End Property 
    Protected Sub OnPropertyChanged(ByVal name As String) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) 
    End Sub 
    Private m_Distance As Decimal 
    Public Property attempt() As Integer 
     Get 
      Return m_attempt 
     End Get 
     Set(value As Integer) 
      m_attempt = value 
     End Set 
    End Property 
    Private m_attempt As Integer 

End Class

是databinds为标签​​的线路如下:


best.DataBindings.Add(New Binding("text", athlete.BestThrow, "distance", False, DataSourceUpdateMode.OnPropertyChanged)) 

我可以告诉大家,物业BestThrow是defintely正在使用Watch更新。但是由于某些原因,标签似乎只反映投掷(0)。距离而不是BestThrow.Distance

我可以改变抛出(0)和标签会改变,如果我添加一个更大的数字任何其他5次尝试,并观察我可以看到BestThrow正在更新。

在此先感谢您的帮助。

马克

回答

0

我认为你有一个错误的何卫青,财产BestThrow从不更新,因为它没有制定者。当您使用手表检查BestThrow值时,它会因为您请求价值而“重新计算”。你需要的是找到一种方法来提高Property Changed事件BestThrow每当添加或从Throws删除项目,因为BestThrow值取决于Throws。事件发生后,UI会再次调用BestThrow's获取更新值。

'You need to execute this code to notify UI that `BestThrow` value has changed 
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("BestThrow")) 

Raisng事件可以手动代码后进行添加/从Throws属性删除项/,或者你可以让ThrowsThrow一个ObservableCollection然后听收集Changed事件。然后在事件处理程序中,您可以提升BestThrow属性更改事件。

+0

感谢您的协助。在Throw设置时引发事件是否足以触发UI更新值,或者是否需要以某种方式设置标签以主动侦听用于BestThrow的PropertyChangedEvent? – mrtechguy

+0

提高事件应该足够了。这就是数据绑定的工作原理。当使用数据绑定时,只要接收到属性值已更改的通知,它就会更新绑定到的属性的值。并且提高属性更改事件是通知UI – har07

+0

的方式进行这些更改后,现在将刷新标签,但仅在第一个字段被更改。因此,如果我有3次投球,第二次距离最远,直到我改变第一距离(即使我将第一距离改变为小于所有其他距离),它将不会显示第二距离。 – mrtechguy