我是C#/ WPF的新手,我想澄清一下我是否正确实现了我的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部分编写逻辑。假设我将有更多要实现的文本框和列表。这是在属性中编码逻辑的正确方法还是我完全忽略了这一点?请帮我理解这个。提前致谢。
答案 0 :(得分:3)
不,这不完全正确。
首先,逻辑通常在模型中,而不是视图模型。也就是说,你有一个过滤器,基本上是UI逻辑,所以它可能就好了。
其次,只有在设置搜索文本时,过滤器才会更改,因此逻辑将进入setter,而不是getter。我也不会内联整个事情,把它放在自己的函数中,以便以后可以重用它:
public String SearchText
{
...
set
{
serachText = value;
NotifyPropertyChanged();
UpdateResults();
}
}
public void UpdateResults()
{
...
}
要记住的一件事(并没有真正的好方法)是,如果该功能需要很长时间才能运行,那么你的用户界面将真正减速用户正在打字。如果执行时间很长,请尝试缩短它,然后考虑在单独的线程上执行它。
答案 1 :(得分:3)
ViewModels只应 负责&#34;转换&#34;数据到视图可以处理的另一种形式(想想INotifyPropertyChanged
,ObservableCollection
等)。
只有 时间,您可以使用具有任何逻辑的ViewModel,而逻辑完全封装在集合中。例如如果你可以从List<T>
获得所需的一切,那么ViewModel就可以有效地拥有所有逻辑。如果您需要超出该值的值,它应该在ViewModel之外。