2017-11-25 164 views
3

我試圖在WPF中實現正確的MVVM體系結構。 我有一個玩,在「模型」部分有一個布爾屬性,說如果我們現在「玩」。綁定到使用更改屬性的屬性

public bool IsPlaying 
    { 
     get 
     { 
      return isPlaying; 
     } 
     set 
     { 
      isPlaying = value; 
      OnPropertyChanged("IsPlaying"); 
     } 
    } 

(請注意,我實現了 「INotifyPropertyChanged的」 接口)在我的ViewModel

,我有一個名爲 「ToggleButtonIcon」 一個ImageSource的屬性:

public ImageSource ToggleButtonIcon 
    { 
     get 
     { 
      if (Model.IsPlaying) 
       return pauseIcon; 
      else 
       return playIcon; 
     } 
    } 

其中我綁定到「切換播放「按鈕在視圖中:

<cc:IconButton x:Name="TogglePlayButton" 
       Style="{StaticResource playButton}" 
       ImageSource="{Binding Path=ToggleButtonIcon, 
       UpdateSourceTrigger=PropertyChanged}" 
       Command="{Binding Path=TogglePlayCommand}"/> 

(這是一個自定義控件,但它的工作,我che cked) 當然,我希望按鈕根據是否正在播放(暫停)以及是否正在播放(播放)來更改圖像圖標。

問題是ToggleButtonIcon不通知它何時更改,我無法在ViewModel部分實現INotifyValueChanged,因爲a。我明白那不是你怎麼做的,b。我不知道它何時發生變化,因爲它取決於Model的IsPlaying屬性。

我曾考慮將ToggleButtonIcon屬性放在模型部分,但這不是「業務邏輯」,所以我認爲這不是正確的做法。

我也想過用轉換器和綁定IconButton直接「IsPlaying模塊」,這可能會工作,但我讀到這裏:How can WPF Converters be used in an MVVM pattern?,你不應該在使用轉換器都在MVVM,因爲你可以做你想做的任何皈依在「ViewModel」部分。

在MVVM體系結構中完成此操作的最佳方法是什麼?

+1

你從哪裏得到的想法:「這不是你怎麼辦呢?」 ViewModels通常實現INotifyPropertyChanged。我會說這對於模型來說實際上並不常見,但你顯然是這麼做的。如果你這樣做,那麼你將不得不在視圖模型中訂閱模型的PropertyChanged事件,並引發相應的更改相關屬性。另一種方法是綁定到模型對象,並使用DataTrigger根據IsPlaying的狀態更改圖像源。 –

+0

「你從哪裏得到這個主意......」 - 我在YouTube上看到過一個例子。 「你將不得不訂閱模型的PropertyChanged事件......」 - 我該怎麼做? 「...並使用DataTrigger根據IsPlaying的狀態更改圖像源」 - 這是什麼意思,我該怎麼做? –

回答

0

MVVM的模型應該只包含類實體,這些實體有時可以有INotiftPropertyChanged,但通常情況下他們不會。

你的意圖是,它是傳達一個狀態,應該在你的視圖模型上。

我建議您將IsPlaying的狀態置於View Model(VM)並綁定到該模型。然後在TogglePlayCommand的命令中,它將在VM上設置該屬性。

這樣一來,兩個項目都會隨着更改而更新。 如果需要,您仍然可以在模型中和虛擬機IsPlayingSetter上新建原始對象,並將類實例屬性設置爲其值(如果需要)。我的博客文章Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding。請注意我如何使用OnPropertyChanged推送其他操作的更改消息,這些操作都可以爲您尋求的靈活性以及視圖模型保持狀態而不是模型。

+0

所以你建議在模型和視圖模型中放置IsPlaying? 因此,「ViewModel.IsPlaying」將從「Model.IsPlaying」中獲取/設置其值? –

+0

我寧願在ViewModel中保留任何視圖操作,但它不清楚OP爲什麼在模型上使用它。 – OmegaMan

1

對於我來說,IsPlaying應該在ViewModel中,並且實現更改通知,因爲它代表了應用程序的排序狀態。

爲了解決這個問題,我會建議服用ToggleButtonIcon出視圖模型,並(通過其Style)創建於IconButton控制DataTrigger,結合到IsPlaying屬性(在視圖模型),並改變基於ImageSource財產在那。

0

你應該把布爾的類,它實現接口INotifyPropertyChange: 下面的例子:

public class Game : INotifyPropertyChanged 
{ 
    private bool _isPlaying; 

    public string IsPlaying 
    { 
     get { return _isPlaying; } 
     set { 
      _isPlaying = value; 
      this.NotifyPropertyChangedBool();  
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChangedBool() 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new 
          PropertyChangedEventArgs("IsPlaying")); 
     } 
    } 
+0

這就是我所做的! (在「模型」槓桿),但我需要綁定一個圖像,而不是布爾值。 –