lazy loading in TabControls (MVVM)
I have an TabControl which displays a collection of my ViewModels. The mapping between ViewModel and View is implemented by DataTemplate. I use MVVM but without PRISM (for historical reasons). The ViewModel’s Base class has a method Load
which load information. What I want to do is to call this method only when a TabItem corresponding to the current ViewModel is chosen (lazy loading). Any ideas?
PS 开发者_如何学GoI found answers to a similar question - Lazy loading WPF tab content but I can’t understand how to use approach 2 in MVVM.
TabItem as any Selector item has the IsSelected property. You may try to bind it with view model using two-way binding. When model's IsSelected set to true for the first time, you may load your data.
XAML:
<TabControl ...>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected,Mode=TwoWay}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
Sample model:
public class MyViewModel : INotifyPropertyChanged
{
private bool _isLoaded;
private void Load()
{
// code
}
private bool _isSelected;
public bool IsSelected
{
get
{
return this._isSelected;
}
set
{
if (this._isSelected != value)
{
this._isSelected = value;
if (this._isSelected && !this._isLoaded)
{
this.Load();
this._isLoaded = true;
}
var propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Another way. This is basically simulating a SelectedTabChanged
event in MVVM.
It works by binding the Name
property of the tab to a SelectedTabName
property in the viewmodel to which you can do whatever you want (including preventing tab changes by setting the value back to its previous value).
ViewModel
public string _selectedTabName;
public string SelectedTabName
{
get { return _selectedTabName; }
set
{
if (_selectedTabName != value)
{
_selectedTabName = value;
RaisePropertyChanged("SelectedTabName");
if (SelectedTabName == "EVENTS" && EventsLoaded == false)
{
LoadEvents();
}
if (SelectedTabName == "MESSAGES" && MessagesLoaded == false)
{
LoadMessages();
}
}
}
}
XAML
<TabControl SelectedValuePath="Name" SelectedValue="{Binding SelectedTabName}">
<TabItem Header="Events" Name="EVENTS">
...
</TabItem>
<TabItem Header="Messages" Name="MESSAGES">
...
</TabItem>
</TabControl>
精彩评论