TabControls(MVVM)中的延迟加载

时间:2011-01-21 08:07:39

标签: wpf mvvm

我有一个TabControl,它显示了我的ViewModel的集合。 ViewModel和View之间的映射由DataTemplate实现。我使用MVVM但没有PRISM(由于历史原因)。 ViewModel的Base类有一个加载信息的方法Load。我想要做的是仅在选择与当前ViewModel相对应的TabItem(延迟加载)时调用此方法。有任何想法吗? PS我找到了类似问题的答案 - Lazy loading WPF tab content但我无法理解如何在MVVM中使用方法2。

2 个答案:

答案 0 :(得分:12)

TabItem作为任何Selector项具有IsSelected属性。您可以尝试使用双向绑定将其与视图模型绑定。当模型的IsSelected第一次设置为true时,您可以加载数据。

XAML:

<TabControl ...>
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="IsSelected"
                    Value="{Binding Path=IsSelected,Mode=TwoWay}"/>
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

样本模型:

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;
}

答案 1 :(得分:5)

另一种方式。这基本上模拟了MVVM中的SelectedTabChanged事件。

它的工作原理是将选项卡的Name属性绑定到viewmodel中的SelectedTabName属性,您可以根据需要执行任何操作(包括通过将值设置回以前的值来防止更改选项卡)。

视图模型

    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>