2014-12-09 63 views
2

我使用的是Prism 5和Visual Basic,但我想C#中的解決方案對我來說也是有效的。當調用SetProperty時,OnPropertyChanged沒有被觸發

我的問題是,這個代碼工作正常:

Private Property _nombreEnvio As String 
Public Property nombreEnvio As String 
    Get 
     Return _nombreEnvio 
    End Get 
    Set(value As String) 
     SetProperty(_nombreEnvio, value) 
     OnPropertyChanged("nombreEnvio") 
    End Set 
End Property 

但如果我刪除調用OnPropertyChange行,它不會更新視圖中的字段:

Private Property _nombreEnvio As String 
Public Property nombreEnvio As String 
    Get 
     Return _nombreEnvio 
    End Get 
    Set(value As String) 
     SetProperty(_nombreEnvio, value) 
     ' THIS CODE DOES NOT REFRESH THE VIEW 
    End Set 
End Property 

它假設SetProperty調用應該調用OnPropertyChanged,但它不會。它有一個奇怪的行爲,它用最後一個值更新視圖。我自己解釋一下,因爲它很複雜:

  • 如果nombreEnvio是CARLOS,我將它設置爲PEDRO,它不更新視圖,它仍然顯示CARLOS。
  • 如果然後我將它設置爲安東尼奧,這表明PEDRO視圖
  • 如果當時我把它設置爲MIGUEL話,就說明ANTONIO在視圖
  • 等等......總是最後一個值,而不是一套現在

而只是添加OnPropertyChanged行,它工作正常。

任何人都可以解釋我爲什麼會這樣?

非常感謝您

已更新30/01/2015 我創建了一個新的VB項目(名爲TestPrismVB),安裝棱鏡和我寫了這個簡單的代碼:

Imports Microsoft.Practices.Prism.Mvvm 

Public Class pruebaViewModel 
    Inherits BindableBase 

    Private Property _oneProperty As String 
    Public Property oneProperty As String 
     Get 
      Return _oneProperty 
     End Get 
     Set(value As String) 
      SetProperty(_oneProperty, value) 
      'IF I UNCOMMENT THIS LINE, IT WORKS: 
      'OnPropertyChanged("oneProperty") 
     End Set 
    End Property 

    Private Property _anotherProperty As String 
    Public Property anotherProperty As String 
     Get 
      Return _anotherProperty 
     End Get 
     Set(value As String) 
      SetProperty(_anotherProperty, value) 
      oneProperty = value 
     End Set 
    End Property 
End Class 

而XAML文件MainWindow.xaml:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:TestPrismVB" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <vm:pruebaViewModel/> 
    </Window.DataContext> 
    <StackPanel> 
     <TextBox Text="{Binding anotherProperty, UpdateSourceTrigger=PropertyChanged}"/> 
     <TextBlock Text ="{Binding oneProperty}"/> 
    </StackPanel> 
</Window> 

如果運行ŧ他的簡單項目,然後鍵入1234,您將看到TextBlock更新了一步(它將顯示123而不是1234)。

它是一個VB錯誤?棱鏡bug?難道我做錯了什麼?

謝謝

+1

我不熟悉的棱鏡,但你不應該調用OnPropertyChanged喜歡第一個片段?僅僅看這個例子:http://msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx – Capellan 2014-12-09 12:48:12

+0

我認爲這是無棱鏡的方式。看看這個博客,它很好解釋:http://blog.pluralsight.com/async-validation-wpf-prism。謝謝 – 2014-12-09 12:53:59

+0

更多數據:我測試了這裏解釋的DoSomething函數,http://10rem.net/blog/2013/02/25/using-callermembername-for-property-change-notification-in-xaml-apps,以及CallerMemberName工作正常。我不知道什麼是錯的。 – 2014-12-10 09:08:57

回答

3

嗯,我現在可以幫你。我不是Visual Basic開發人員,所以我沒有看到代碼中的「錯誤」,但有經驗的VB.NET專家可以在5分鐘內幫助您。

所以棱鏡和Visual Basic做的所有事情,正是因爲他們應該做的,問題是你的代碼引起的,此行是爲它負責:

Private Property _oneProperty As String 

SetProperty()方法接受屬性存儲ByRef ,但是您提供屬性作爲存儲。在這種情況下,當你傳遞一個屬性作爲ByRef參數,VB複製屬性值給一個臨時變量,傳遞可變ByRef和在可變的屬性分配回的值。

的觀察到的行爲有一個簡單的解釋:棱鏡引發PropertyChanged事件和WPF綁定請求新的屬性值只是前,將通過VB從已實際傳遞ByRef臨時變量分配。

TL; DR解決的辦法是:

替換此

Private Property _oneProperty As String 
Private Property _anotherProperty As String 

與此

Private _oneProperty As String 
Private _anotherProperty As String 
+0

就這麼簡單,我瘋了。非常感謝你,這是正確的解決方案。 – 2015-02-04 08:29:51

相關問題