2014-09-22 66 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之外。