2014-09-22 95 views
4

我是新來的C#/ WPF,我想澄清一下我是否有適當的實現我的ViewModel。困惑於在哪裏放置邏輯代碼在ViewModel

我創建了一個帶搜索文本框和結果列表框的簡單窗口。

<TextBox Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
<ListBox ItemsSource="{Binding Results}" /> 

然後,我有一個ViewModel與下面的代碼。

private List<string> lstStr; 

    public ViewModel() 
    { 
     lstStr = new List<string>(); 
     lstStr.Add("Mike"); 
     lstStr.Add("Jerry"); 
     lstStr.Add("James"); 
     lstStr.Add("Mikaela"); 
    } 

    public List<string> LstStr 
    { 
     get 
     {     
      return lstStr; 
     } 

     set 
     { 
      if (lstStr != value) 
      { 
       lstStr = value; 
       OnPropertyChanged("LstStr"); 
      } 
     } 
    } 

    private string searchText; 
    public string SearchText 
    { 
     get 
     { 
      return searchText; 
     } 

     set 
     { 
      if (searchText != value) 
      { 
       searchText = value; 
       OnPropertyChanged("SearchText"); 
       UpdateResults(); 
      } 
     } 
    } 

    private ObservableCollection<string> results = new ObservableCollection<string>(); 
    public ObservableCollection<string> Results 
    { 
     get 
     {     
      return results; 
     } 

     set 
     { 
      if (results != value) 
      { 
       results = value; 
       OnPropertyChanged("Results"); 
      } 
     } 
    } 

    public void UpdateResults() 
    { 
     int i = 0; 
     results.Clear(); 
     while (i < LstStr.Count) 
     { 
      if (LstStr.ElementAt(i).ToString() != null) 
      { 
       if (searchText != null && searchText != "") 
       { 
        if (LstStr.ElementAt(i).Trim().Contains(searchText)) 
        { 
         results.Add(LstStr.ElementAt(i)); 
         Console.WriteLine(LstStr.ElementAt(i)); 
        } 
       } 

       else 
        results.Clear(); 
      } 

      else 
       Console.WriteLine("NULL"); 

      i++; 
     } 
    } 

我看到自己在ViewModel的代碼的Get或Set部分編寫邏輯。比方說,我會有更多的文本框和列表,希望實現。這是在屬性中編寫我的邏輯的正確方法,還是我完全忽略了這一點?請幫我理解這一點。提前致謝。

+1

ViewModels實際上應該很愚蠢。你需要定義他們應該包含哪些屬性,以及如何定義這些屬性(必需的,範圍內的,特定的長度等)。但是,爲這些屬性生成值的邏輯實質上就是您的業務層,應該在別處生存。 – Ellesedil 2014-09-22 18:25:53

+3

不,你不應該把邏輯放在那裏。這樣想一下:'SearchText' *做什麼*?它沒有意義,它只是代表正在搜索的文本。 *方法*做事,屬性不要。 ViewModels大體上不是「do-ers」,它只是實際視圖和邏輯實際執行位置之間的層。 – tnw 2014-09-22 18:26:22

+1

@Ellesedil搜索過濾器*可能*是視圖模型的一部分,但肯定不是他放置的位置。過濾器不是業務邏輯,它的UI邏輯。 – BradleyDotNET 2014-09-22 18:30:51

回答

3

不,這不完全正確。

首先,邏輯通常進入模型,而不是視圖模型。也就是說,你有一個過濾器,這基本上是UI邏輯,所以它可能在這裏。

二,過濾器只會在你設置設置時發生改變,所以邏輯會在setter中去,而不是getter。我也不會內嵌了整個事情,把它放在自己的功能,所以您可以在以後重新使用它:

public String SearchText 
{ 
    ... 
    set 
    { 
     serachText = value; 
     NotifyPropertyChanged(); 
     UpdateResults(); 
    } 
} 

public void UpdateResults() 
{ 
    ... 
} 

有一兩件事要記住(並沒有一個真正的好辦法解決這個問題)如果該功能需要很長時間才能運行,那麼您的用戶界面將會在用戶輸入時減慢速度真實。如果執行時間很長,請嘗試縮短它,然後考慮在單獨的線程上執行它。

3

的ViewModels應該有只有的「轉換」數據轉換成另一種形式的視圖可以處理的責任(認爲INotifyPropertyChangedObservableCollection等)

只有時間,其中你會逃脫ViewModel具有邏輯的任何是邏輯完全封裝在集合中的時候。例如如果你可以從List<T>中得到所需的一切,那麼ViewModel有效地擁有了所有的邏輯。如果你需要超出這個值,它應該在ViewModel之外。