在多个继承的对象上获取INotifyPropertyChanged

时间:2011-09-02 08:36:58

标签: .net vb.net inheritance inotifypropertychanged

嗯,我不认为我的头衔很有效率,但无论如何。让我更准确地解释一下。

我有一个班级,车辆。我创建了两个子类,Car和Plane。我想监视速度,这是一个车辆属性,并将其绑定到WPF中的控件(例如标签或图像)。当我创建一个仅用于观察Speed属性的静态类时,只要使用Speed属性名称声明INotifyPropertyChanged,它就可以工作。

但问题是,我必须通过查看XML文件和反序列化我的对象来动态创建多个汽车和飞机,并创建多个Car或Plane UserControl(请不要讨论这种工作方式)。所以我必须在Vehicle Class中获得Speed属性(这是正常的),并且我必须在每个创建的Vehicle的每个Speed上获得一个INotifyPropertyChanged。 所以,我的汽车和飞机都已加载,我必须获得所有速度,但我无法通过车辆创建静态速度属性。顺便说一下,通过在setter中使用INotifyPropertyChanged创建一个非静态Speed属性(例如int作为int),它不起作用。事件似乎被提出,但我的转换器没有被触发,我的控件也没有更新。

在我的车辆类

Private SpeedValue As Integer
<XmlIgnore()>
Public Property Speed() As Short
    Get
        Return SpeedValue 
    End Get
    Set(ByVal value As Short)
        SpeedValue = value
        NotifyPropertyChanged("Speed")
    End Set
End Property

Public Event PropertyChanged As PropertyChangedEventHandler _
    Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged(ByVal info As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))

End Sub

在我的代码隐藏

Dim b As Binding = New Binding()
    b.Source = theVehicle
    b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    b.Path = New PropertyPath(theVehicle.Speed)
    b.Path = New PropertyPath("Speed")
    b.Converter = New SpeedValueToPicturePathConverter()
    b.ConverterParameter = GetType(Vehicle)
    img_fonctionnement.SetBinding(Image.SourceProperty, b)

我也尝试过使用lambda表达式,但我无法弄清楚如何使整个事情发挥作用。我还有一个“已添加相同键的项目”错误,但我改变了我的代码,我不记得如何。 我知道我的解释很糟糕,但很难解释(我是法国人;))。拜托,如果你可以帮助我,那就太好了,因为我有点卡在这里。

更新

更多代码:

这是在我的WatchTower线程中,每10次执行一次。这里的所有代码都可以使用

' theConfig is a singleton which represent my XML config file deserialized
' Getting all vehicles declared in this file works by doing this
For Each vehic As Vehicle In theConfig.Vehicles
        Dim realTimeSpeed = server.Read("speed") 'reading the speed on some distant server - don't discuss this, it works fine
        If (Not vehic.Speed = realTimeSpeed) Then
            vehic.Speed = realTimeSpeed
        End If

    Next

这是我为theConfig XML文件

中声明的每个Vehicle添加一个TabItem的地方
'This actually works, a tab is added for each vehicle
For Each vehic As Vehicle In theConfig.Vehicles
        Dim vehicTabItem As TabItem = New TabItem()
        vehicTabItem.Header = vehic.Description
        If (TypeOf vehic Is Car) Then
        'Adding the CarView UserControl of my own
            vehicTabItem.Content = New CarView(DirectCast(vehic, Car))
            TabControl1.Items.Add(vehicTabItem)
        ElseIf (TypeOf vehic Is Plane) Then
            vehicTabItem.Content = New PlaneView(DirectCast(vehic, Plane))
            TabControl1.Items.Add(vehicTabItem)

        End If

    Next

这是在CarView文件(WPF用户控件,代码隐藏)

Public Class CarView

Private theCar As Car

Public Sub New(ByVal theCar As Car)

    InitializeComponent()

    Me.theCar = theCar 

    Dim b As Binding = New Binding("Speed")
    b.Source = theCar
    b.Converter = New SpeedValueToPicturePathConverter()
    b.ConverterParameter = GetType(Vehicle)
    'img_fonctionnement is created in the graphic designer in Visual Studio in xaml
    'Remember, this binding works whn I use a static property just for testing
    img_fonctionnement.SetBinding(Image.SourceProperty, b)

End Sub

此部分的PlaneView类几乎相同。

我确认转换器只是在创建选项卡时第一次触发,因为我在转换函数定义上放了一个断点。之后,转换器再也不会被触发。因此显示图片img_fonctionnement,但它永远不会更新。但是我发誓,Speed属性已经更新了。在调试器的帮助下,我知道INotifyPropertyChanged(在Speed的setter中)。

并且“已经添加了具有相同键的项目”(显示在messageBox中,而不是作为例外)似乎只有在我使用调试器时才会出现。在正常执行模式下,它永远不会显示。

2 个答案:

答案 0 :(得分:0)

我不明白您用来创建绑定的代码。

应该如此简单:

Dim b As Binding = New Binding("Speed")
b.Source = theVehicle
b.Converter = New SpeedValueToPicturePathConverter()
b.ConverterParameter = GetType(Vehicle)
img_fonctionnement.SetBinding(Image.SourceProperty, b)

如果这没有帮助,可能还有其他问题:

  • theVehicle真的是正确的实例吗?
  • 该实例的速度真的更新了吗?

答案 1 :(得分:0)

我的坏。我正在刷新一个车辆集合,但我正在创建我的标签与另一个独立的车辆集合(基于相同的XML文件)。我创建了一个单身人士,但我并没有在任何地方使用它。

我太糟糕了。

谢谢,丹尼尔,无论如何你帮助了我,即使你的答案不是我问题的原因;)