【问题标题】:Treating multiple tabs as separate Views with separate ViewModels in WPF在 WPF 中使用单独的 ViewModel 将多个选项卡视为单独的视图
【发布时间】:2014-08-30 07:04:34
【问题描述】:

在 WPF 中,我有一个窗口,其中包含一个带有四个 TabItem 的 TabControl。每个 TabItem 都有一个 Grid:

<TabItem Header="Input" Name="tabItem1">
   <Grid></Grid>
</TabItem>

在我的代码隐藏中,我需要指定一个指向 ViewModel 的数据上下文。我不想让一个 ViewModel 来处理所有四个选项卡,而是希望每个选项卡都有一个 ViewModel。这意味着每次都有不同的 DataContexts。

有没有办法以干净的方式实现这一目标?

【问题讨论】:

  • 为什么不只在 XAML 中设置 DataContext?你能更具体地说明清洁方式吗?
  • 恐怕我不能更具体地说明“干净的方式”,我是 WPF 的新手。你能给我一个仅在 XAML 中为每个 TabItem/Grid 设置 DataContext 的示例吗?
  • 我不认为有办法让它仅限XAML。我可以想到一种“干净”的方法来使其仅成为 XAML,但它需要一些冗余代码
  • @John Smith - 我已经为您想要的更清洁的方法添加了答案。看看有没有帮助。

标签: c# wpf mvvm datacontext


【解决方案1】:

您只能通过仅在 XAML 中声明实例并将 DataContext 绑定到该实例来在 XAML 中设置 DataContext

但是由于您要求更清洁的方式,所以理想的是将 TabControl 的 ItemsSource 绑定到 ViewModel 的集合,以便所有 tabItems 自动具有不同的 DataContext。


首先创建 DummyViewModel 并在您的主窗口 ViewModel 中有 ObservableCollection&lt;DummyViewModel&gt; 集合。

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        ViewModelCollection = new ObservableCollection<DummyViewModel>();
        ViewModelCollection.Add(new DummyViewModel("Tab1", "Content for Tab1"));
        ViewModelCollection.Add(new DummyViewModel("Tab2", "Content for Tab2"));
        ViewModelCollection.Add(new DummyViewModel("Tab3", "Content for Tab3"));
        ViewModelCollection.Add(new DummyViewModel("Tab4", "Content for Tab4"));
    }

    public ObservableCollection<DummyViewModel> ViewModelCollection { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class DummyViewModel
{
    public DummyViewModel(string name, string description)
    {
        Name = name;
        Description = description;
    }
    public string Name { get; set; }
    public string Description { get; set; }
}

并像这样在 XAML 中与集合绑定:

<TabControl ItemsSource="{Binding ViewModelCollection}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding Description}"/>
            </Grid>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

ItemTemplate 是为 标签项的标题 定义的,ContentTemplate 是为 定义的各个 tabItems 的内容

将创建四个选项卡项,每个选项卡项 DataContext 设置为单独的 DummyViewModel 实例。


快照:

【讨论】:

  • 所以,假设我在 Tab1 中有一个带有绑定到描述的文本框,我想通过单击按钮将描述更改为“Hello world”。我该怎么做?
  • UpdateSourceTrigger 的默认值为TextBoxLostFocus。因此,一旦您失去焦点,就会在属性 Description 上设置文本。
猜你喜欢
  • 2019-10-03
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多