Получить INotifyPropertyChanged для нескольких унаследованных объектов - PullRequest
0 голосов
/ 02 сентября 2011

Ну, я не думаю, что мой титул достаточно эффективен, но в любом случае. Позвольте мне объяснить более точно.

У меня есть класс, Автомобиль. Я создал два детских класса, Автомобиль и Самолет. Я хочу отслеживать скорость, которая является свойством транспортного средства, и привязывать ее к элементу управления (например, метке или изображению) в WPF. Когда я создаю статический класс, единственной целью которого является наблюдение за свойством Speed, оно работает, поскольку INotifyPropertyChanged объявляется с именем свойства Speed.

Но проблема в том, что мне нужно динамически создавать несколько автомобилей и самолетов, просматривая XML-файл и десериализовывая мои объекты, и создавая несколько пользовательских элементов управления Car или Plane (не будем обсуждать этот способ работы, пожалуйста). Поэтому я должен получить свойство Speed ​​внутри класса Vehicle (что является нормальным), и мне нужно получить INotifyPropertyChanged для каждой скорости каждого созданного транспортного средства. Итак, мои Автомобили и Самолеты загружены, и я должен получить все скорости, но я не могу создать статическое свойство Скорости с помощью Vehicle. Между прочим, при создании нестатического свойства Speed ​​(например, int) в классе Vehicle с параметром INotifyPropertyChanged, заданным в установщике, оно не работает. Кажется, что событие инициировано, но мой конвертер не запущен, и мои элементы управления не обновляются.

В моем классе транспортных средств

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)

Я тоже пробовал с лямбда-выражениями, но не мог понять, как заставить все это работать. У меня также была ошибка «элемент с тем же ключом уже добавлен», но я так изменил свой код, что не могу вспомнить, как. Я знаю, что мои объяснения плохие, но это довольно сложно объяснить (и я француз;)). Пожалуйста, если бы вы могли мне помочь, было бы неплохо, потому что я немного застрял здесь.

UPDATE

Дополнительный код:

Это в моей ветке 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

Здесь я добавляю TabItem для каждого Транспортного средства, объявленного в XML-файле theConfig

'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 usercontrol, codebehind)

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 (в установщике скорости) поднимается, насколько я знаю, с помощью отладчика.

И «элемент с тем же ключом уже был добавлен» (который появляется в блоке сообщений, а не как исключение), кажется, появляется только тогда, когда я слишком долго с отладчиком. В обычном режиме выполнения никогда не показывается.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2011

Мой плохой.Я обновлял коллекцию транспортных средств, но я создавал свои вкладки с помощью другой независимой коллекции транспортных средств (основанной на том же XML-файле).Я создал синглтон, но не везде его использовал.

Я такой плохой.

Спасибо, Дэниел, ты все равно мне помог, даже если твой ответ не был причиноймоя проблема;)

0 голосов
/ 02 сентября 2011

Я не понимаю код, который вы используете для создания привязки.

Это должно быть так просто:

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 действительно правильным экземпляром?
  • Действительно ли скорость этого экземпляра обновлена?
...