2013-08-30 2 views
3

Все, я создал TabControl для хранения Tabitem s, которые содержат один тип управления. Разметка для MainWindow.xamlбыл, как показано нижеОтображение нескольких типов управления в TabControl

... 
<TabControl x:Name="tabControl" 
      ItemsSource="{Binding Path=Workspaces}" 
      SelectedIndex="{Binding SelectedIndex}" 
      IsSynchronizedWithCurrentItem="true" 
      HorizontalContentAlignment="Stretch" 
      VerticalContentAlignment="Stretch" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Stretch" 
      TabStripPlacement="Top" 
      Margin="5,0,5,0"> 
    <TabControl.ItemContainerStyle> 
     <Style TargetType="TabItem"> 
      <Setter Property="Header" Value="{Binding Path=DisplayName}"/> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      <Setter Property="VerticalContentAlignment" Value="Stretch"/> 
     </Style> 
    </TabControl.ItemContainerStyle> 
    <TabControl.ContentTemplate> 
     <DataTemplate> 
      <Views:ResourceControl DataContext="{Binding}" 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch"/> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 
... 

Это работало отлично подходит для моего Views:ResourceControl с, но теперь я хочу, чтобы расширить тип управления, отображаемых в TabControl. Для этого я создаю элементы управления, которые оба связаны для просмотра моделей, которые наследуют от базового «WorkspaceViewModel» и я создал файл следующего ресурса

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:ViewModels="clr-namespace:ResourceStudio.ViewModels" 
        xmlns:Views="clr-namespace:ResourceStudio.Views"> 
    <DataTemplate DataType="{x:Type ViewModels:ResourceDataViewModel}"> 
     <Views:ResourceControl /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type ViewModels:StartPageViewModel}"> 
     <Views:StartPageControl/> 
    </DataTemplate> 
    <DataTemplate x:Key="WorkspacesTemplate"> 
     <TabControl x:Name="tabControl" 
        IsSynchronizedWithCurrentItem="true" 
        ItemsSource="{Binding}" 
        SelectedIndex="{Binding SelectedIndex}" 
        HorizontalContentAlignment="Stretch" 
        VerticalContentAlignment="Stretch" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        TabStripPlacement="Top" 
        Margin="5,0,5,0"> 
      <TabControl.ItemContainerStyle> 
       <Style TargetType="TabItem"> 
        <Setter Property="Header" Value="{Binding Path=DisplayName}"/> 
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
        <Setter Property="VerticalContentAlignment" Value="Stretch"/> 
       </Style> 
      </TabControl.ItemContainerStyle> 
     </TabControl> 
    </DataTemplate> 
</ResourceDictionary> 

и теперь в MainWindow.xaml у меня есть

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="MainWindowResources.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
     <Style x:Key="DescriptionHeaderStyle" TargetType="Label"> 
      <Setter Property="FontSize" Value="22" /> 
      <Setter Property="HorizontalAlignment" Value="Center" /> 
     </Style> 
    </ResourceDictionary> 
</Window.Resources> 
... 
<ContentControl 
    Content="{Binding Path=Workspaces}" 
    ContentTemplate="{StaticResource WorkspacesTemplate}"> 
</ContentControl> 

Кажется, что привязки регистрируются для разных представлений, которые я хочу отображать в качестве отображения вкладок с соответствующими заголовками. Однако фактические элементы управления не отображаются, пока я не загружу другую форму. Кажется, что SelectedIndex не является обязательным, и представления не обновляются при переключении/загрузке элемента табуляции.

Как я могу изменить WorkspaceTemplate, чтобы исправить эту проблему?

Спасибо за ваше время.


Редактировать. Запрошенная информация о MainViewModel.

public class MainWindowViewModel : WorkspaceViewModel 
{ 
    private readonly IDialogService dialogService; 
    private WorkspaceViewModel selectedWorkspace; 
    private ObservableCollection<WorkspaceViewModel> workspaces; 
    private Dictionary<string, string> resourceDictionary; 

    public MainWindowViewModel() 
    { 
     base.DisplayName = "SomeStringName"; 
     resourceDictionary = new Dictionary<string, string>(); 
     dialogService = ServiceLocator.Resolve<IDialogService>(); 
     Contract.Requires(dialogService != null); 
    } 

    ... 

    private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.NewItems != null && e.NewItems.Count != 0) 
      foreach (WorkspaceViewModel workspace in e.NewItems) 
       workspace.RequestClose += this.OnWorkspaceRequestClose; 

     if (e.OldItems != null && e.OldItems.Count != 0) 
      foreach (WorkspaceViewModel workspace in e.OldItems) 
       workspace.RequestClose -= this.OnWorkspaceRequestClose; 
    } 

    private void OnWorkspaceRequestClose(object sender, EventArgs e) 
    { 
     WorkspaceViewModel workspace = sender as WorkspaceViewModel; 
     workspace.Dispose(); 
     int currentIndex = Workspaces.IndexOf(workspace); 
     this.Workspaces.Remove(workspace); 
     if (this.Workspaces.Count > 0) 
      this.SetActiveWorkspace(Workspaces[currentIndex - 1]); 
    } 

    private void SetActiveWorkspace(WorkspaceViewModel workspace) 
    { 
     Debug.Assert(this.Workspaces.Contains(workspace)); 
     ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.Workspaces); 
     if (collectionView != null) 
      collectionView.MoveCurrentTo(workspace); 
    } 

    public WorkspaceViewModel SelectedWorkspace 
    { 
     get { return selectedWorkspace; } 
     set { selectedWorkspace = value; } 
    } 

    private int selectedIndex = 0; 
    public int SelectedIndex 
    { 
     get { return selectedIndex; } 
     set 
     { 
      if (selectedIndex == value) 
       return; 
      selectedIndex = value; 
      OnPropertyChanged("SelectedIndex"); 
     } 
    } 

    /// <summary> 
    /// Returns the collection of available workspaces to display. 
    /// A 'workspace' is a ViewModel that can request to be closed. 
    /// </summary> 
    public ObservableCollection<WorkspaceViewModel> Workspaces 
    { 
     get 
     { 
      if (workspaces == null) 
      { 
       workspaces = new ObservableCollection<WorkspaceViewModel>(); 
       workspaces.CollectionChanged += this.OnWorkspacesChanged; 
      } 
      return workspaces; 
     } 
    } 
    ... 
} 
+0

Можем ли мы увидеть ваш код VM, содержащий свойство 'SelectedIndex', и что вы имеете в виду при загрузке формы? – AsitK

+0

Уверенный, обновляя вопрос ... – MoonKnight

+0

@AsitK вопрос был обновлен. Спасибо за ваше время ... – MoonKnight

ответ

1

Я столкнулся с чем-то похожим с помощью вашего кода. Не уверен, что он такой же. Когда мое приложение загрузилось, он показал 1-ю вкладку (0-е) с ее соответствующим содержимым. Когда выбирается второй контент, регион становится пустым и ничего не происходит.

я переехал Content="{Binding Path=Workspaces}" к TabControl т.е.

Content="{Binding}" и

<TabControl ItemsSource="{Binding Workspaces}"/> 

и начал показывать контент для вкладок. Я использовал более урезанную версию вашей виртуальной машины. просто коллекция WorkSpaces.

+0

Это замечательно. Спасибо. Хотя я не совсем уверен, почему это работает над вышеприведенным подходом. Каскадирование привязки должно подниматься по дереву элементов, и мне кажется, что это происходит _down_ !? – MoonKnight

+1

Для ваших первоначальных привязок я проверил ошибки Binding Errors в окне Output и показал, что свойство 'SelectedIndex' не было найдено в' WorkspaceVM', т. Е. Искало его на неправильной виртуальной машине. Более того, если ничего не было выбрано, и я минимизировал окно, сфокусировав клавиатуру на какое-то другое окно и вернувшись к ней, тогда он показал выбранное содержимое вкладки .. странно .. !!!! Новое связывание убедило, что 'DataContext' для вашего' TabControl' был 'MainWindowVM' и' SelectedIndex' был извлечен из него. Похоже на сохранение IEnumberable, поскольку DataContext - это не очень хорошая идея. – AsitK

+0

Опять же, спасибо за ваше время ... – MoonKnight

Смежные вопросы