2013-12-08 42 views
0

我有一個C#Windows Phone 8 MVVM應用程序與Fody PropertyChanged軟件包安裝。我已經添加了ImplementPropertyChanged指令中的類聲明之前:儘管在Windows Phone 8應用程序中使用了Fody PropertyChanged包,但數據綁定視圖元素仍未更新?

[CompilerGenerated] 
[GeneratedCode("Radarc", "4.0")] 
[ImplementPropertyChanged] 
public partial class MilitaryRobots_VideosViewModel : ViewModelsBase.VMBase, IViewModels.IMilitaryRobots_VideosViewModel, INotifyPropertyChanged 

我在班上以下兩個屬性,我結合景觀元素:

private Visibility _showDetailsVideo = Visibility.Collapsed; 

    public Visibility ShowDetailsVideo 
    { 
     get 
     { 
      return this._showDetailsVideo; 
     } 

     set 
     { 
      this._showDetailsVideo = value; 
      this.ShowMainScreen = value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; 
     } 
    } 

    private Visibility _showMainScreen = Visibility.Visible; 

    /// <summary> 
    /// Never set this property, instead set ShowDetailsVideo instead. 
    /// </summary> 
    public Visibility ShowMainScreen 
    { 
     get 
     { 
      return this._showMainScreen; 
     } 

     private set 
     { 
      this._showMainScreen = value; 
     } 
    } 

一個查看元素的Visibility屬性必然與View Model的ShowDetailsVideo屬性有關。另一個查看元素的可見性屬性綁定到查看模型的ShowMainScreen屬性。在運行時,訪問屬性獲取者,指示綁定的View元素對正在訪問屬性至少一次。此外,這兩個視圖元素確實具有適當的可見性狀態。但是,如果我改變ShowDetailsVideo酒店在運行時,制定者被訪問,但不干將,表明性質和視圖元素屬性之間的佈線不工作,儘管我使用Fody PropetyChanged的包。財產訪問行爲與Fody包甚至不在那裏相同。

我該如何解決這個問題並使其工作,以便在運行時正確更新Visibility屬性的視圖元素對?我認爲Fody PropertyChanged軟件包應該使實施屬性更改通知變得不必要。

+0

我總是使用'Visibility'打交道時的轉換器下降BindableBase類,你有沒有嘗試過? – Tico

+0

@Tico你綁定到一個布爾屬性?這通常是有人使用具有可見性屬性的轉換器。如果你看看我的代碼,我綁定到已經是可見類型的屬性,所以不需要轉換器。 –

+0

是的,羅伯特,我的第一個轉換器是經典的布爾示例。但是你可以使用Converter實現你想要的。在一種情況下,我使用其中一個來根據輸入的字符數量來設置文本框的寬度。我說的是,試試看。 – Tico

回答

0

我在添加這個答案,因爲這個問題花了幾個小時才能找到並修復。我正在將答案標記爲社區wiki,因爲我沒有爲此尋求功勞,只是爲了拯救別人我診斷它的麻煩。

以下是更正後的視圖模型代碼,以使屬性更改通知正常工作。視圖模型中的可綁定屬性發生更改時,View並未更新,因爲我沒有在屬性設置器中調用基本的SetProperty()方法,而是僅執行直接分配,因此未觸發屬性更改通知。你可以在我原來的帖子中的屬性設置器中看到這個。只需添加SetProperty()調用即可解決所有問題。

所以,如果您的視圖模型類從像BindableBase(見下文)一類下降,你不需要Fody的PropertyChanged插件可言,但要確保你在你的屬性設置器調用的SetProperty()而不是做直接分配給支持該屬性的數據成員。

更新屬性setter/getter方法

private Visibility _showDetailsVideo = Visibility.Collapsed; 

    public Visibility ShowDetailsVideo 
    { 
     get 
     { 
      return this._showDetailsVideo; 
     } 

     set 
     { 
      SetProperty(ref this._showDetailsVideo, value); 
      this.ShowMainScreen = value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; 
     } 
    } 

    private Visibility _showMainScreen = Visibility.Visible; 

    /// <summary> 
    /// Never set this property, instead set ShowDetailsVideo instead. 
    /// </summary> 
    public Visibility ShowMainScreen 
    { 
     get 
     { 
      return this._showMainScreen; 
     } 

     private set 
     { 
      SetProperty(ref this._showMainScreen, value); 
     } 
    } 

我的視圖模型從

/// <summary> 
/// Abstraction of data-binder that notifies properties changes to the suitable View. 
/// </summary> 
public abstract class BindableBase : INotifyPropertyChanged 
{ 
    /// <summary> 
    /// Event launched when a property of the bindable object has changed. 
    /// </summary> 
    public event PropertyChangedEventHandler PropertyChanged; 

    /// <summary> 
    /// Sets the value of the binded property. 
    /// </summary> 
    /// <typeparam name="T">The generic type.</typeparam> 
    /// <param name="storage">The type of the property.</param> 
    /// <param name="value">The value of the property.</param> 
    /// <param name="propertyName">The name of the property.</param> 
    /// <returns>A boolean indicating the success of the assignation.</returns> 
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]String propertyName = null) 
    { 
     if (Equals(storage, value)) return false; 

     storage = value; 
     OnPropertyChanged(propertyName); 
     return true; 
    } 

    /// <summary> 
    /// Event handler for the PropertyChanged event. 
    /// </summary> 
    /// <param name="propertyName">The name of the property that has changed.</param> 
    protected void OnPropertyChanged(string propertyName = null) 
    { 
     //if (Debugger.IsAttached) 
     // Debug.WriteLine("Property changed: " + propertyName); 

     var eventHandler = PropertyChanged; 
     if (eventHandler != null) 
      eventHandler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    /// <summary> 
    /// Initializes the bindable object. 
    /// </summary> 
    /// <param name="parameters">Dictionary with the parameters.</param> 
    public virtual void Initialize(IDictionary<string, string> parameters) 
    { 

    } 
} 
相關問題