[英]How can I lazy load my view model properties when bound to a tab control?
I'm using MVVM in my WPF application in a master/detail type scenario where I have a list of search results (the master). 我在主/详细类型方案中的WPF应用程序中使用MVVM,其中有搜索结果列表(主)。 When a user selects a result I call Refresh and pass the database key to load the details. 当用户选择结果时,我将调用Refresh并传递数据库密钥以加载详细信息。 The details is a view model with some complex properties. 详细信息是具有一些复杂属性的视图模型。 Each of these properties has a list of items (representing data in a database) along with some other ICommands and properties. 这些属性中的每一个都有一个项目列表(表示数据库中的数据)以及一些其他ICommands和属性。
My view has a tab control where each tab displays the data for one of these complex properties. 我的视图有一个选项卡控件,其中每个选项卡都显示这些复杂属性之一的数据。 I only want to load the list of the complex properties (call the LoadItems() method) if the tab item used to view the data is selected (visible?). 如果选择了用于查看数据的选项卡项(可见?),我只想加载复杂属性的列表(调用LoadItems()方法)。
Here is an abbreviated example: 这是一个简短的示例:
public class MyItem{
public string Id{get;set;}
public DateTime Timestamp{get;set;}
}
public class ComplexClass:INotifyPropertyChanged
{
private Guid _key;
private List<MyItem> _items;
public string Name{get;set;}
public List<MyItem> Items
{
get{
if (_items == null) LoadItems(_key);
return _items;
}
set{
if(Equals(value, _items) return;
_item = value;
OnPropertyChanged("Items");
}
}
public void LoadItems(Guid key){
... //code to load Items from database based on the key.
}
public ComplexClass(string name, Guid key){
Name = name;
_key = key;
}
}
public class MyViewModel:INotifyPropertyChanged
{
private ComplexClass _currentItems;
public ComplexClass CurrentItems
{
get{return _currentItems;}
set{
if(Equals(value, _currentItems) return;
_currentItem = value;
OnPropertyChanged("CurrentItems");
}
}
private ComplexClass _historyItems;
public ComplexClass HistoryItems
{
get{return _historyItems;}
set{
if(Equals(value, _historyItems) return;
_historyItems= value;
OnPropertyChanged("HistoryItems");
}
}
public void Refresh(Guid key){
CurrentItems = new ComplexClass("Foo", key);
HistoryItems = new ComplexClass("Bar", key);
}
}
And here is some example XAML (assume the TabControl's DataContex is an instance of the ViewModel). 这是XAML的示例(假设TabControl的DataContex是ViewModel的实例)。
...
<TabControl>
<TabItem Header="Current Items"
DataContext={Binding CurrentItems}>
...
<ItemsControl ItemsSource={Binding Items}>
....
</ItemsControl>
</TabItem>
<TabItem Header="History Items"
DataContext={Binding HistoryItems}>
...
<ItemsControl ItemsSource={Binding Items}>
....
</ItemsControl>
</TabItem>
</TabControl>
This works the first time. 这是第一次。 The HistoryItems.Items Getter doesn't get called until the "History Items" tab is selected. 在选择“历史记录项”选项卡之前,HistoryItems.Items Getter不会被调用。
But if I call Refresh on the ViewModel instance it calls the Items getter on both CurrentItems and HistoryItems regardless of which tab is selected. 但是,如果我在ViewModel实例上调用Refresh,则无论选择了哪个选项卡,它都会在CurrentItems和HistoryItems上调用Items getter。
Basically I want to improve performance by only loading the data needed. 基本上,我只想通过加载所需的数据来提高性能。 In most cases users will either scroll through search results (calling ViewModel.Refresh) looking at the current items or the history. 在大多数情况下,用户将滚动浏览搜索结果(调用ViewModel.Refresh)以查看当前项或历史记录。 I only want to load both if the user changes tabs. 如果用户更改选项卡,我只想加载两者。
Is there any way that after I call Refresh I can only call LoadItems for either CurrentItems or HistoryItems based on which tab is selected? 在调用“刷新”之后,是否有任何方法只能根据选择的选项卡为CurrentItems或HistoryItems调用LoadItems?
There's a IsSelected
property on TabItem
element. TabItem
元素上有一个IsSelected
属性。
Create two bool
properties in your view model. 在视图模型中创建两个bool
属性。 Bind the same property to both TabItem
element's IsSelected
property. 将相同的属性绑定到两个TabItem
元素的IsSelected
属性。
Call the LoadItems()
in respective set method for the selected tab. 在所选标签的相应set方法中调用LoadItems()
。
Hope that solves your problem :-) 希望能解决您的问题:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.