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 I found answers to a similar question - Lazy loading WPF tab content  but I can’t understand how to use approach 2 in MVVM.
            Asked
            
        
        
            Active
            
        
            Viewed 8,480 times
        
    2
            
            
        
        Community
        
- 1
 - 1
 
        Kirill Lykov
        
- 1,293
 - 2
 - 22
 - 39
 
2 Answers
12
            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;
}
        Marat Khasanov
        
- 3,808
 - 19
 - 22
 
- 
                    1. I can't understand how to use the IsSelected property - I have only TabControl and UserControls which are displayed in it. So I don't have explicit TabItems and don't know how to get them. – Kirill Lykov Jan 21 '11 at 08:52
 - 
                    2. If I even got TabItem, I can't understand ho IsSelected property can help me. Where can I check if IsSelectedIsTrueForThe1stTime then call my Load method? – Kirill Lykov Jan 21 '11 at 08:55
 - 
                    I've added example to my answer – Marat Khasanov Jan 21 '11 at 10:19
 
5
            
            
        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>
        Simon_Weaver
        
- 140,023
 - 84
 - 646
 - 689