2014-09-23 205 views
2

我遇到了一个TabControl问题,我在其中管理(在某些特殊情况下)选择了两个选项卡标题(只有一个显示afaik的主体),并且我无法更改选定的选项卡。在选项卡控制器中选择了两个选项卡

Screenshot

所选标签有大胆的标题文本。

在这张图片中,“Ämnesinformation”和“R43”都被选中。

我有一些看法:

  • 的MainView:主视图,包含只包含图像中的一个项目的TabControl

    我的应用程序的结构如下。

  • SubstanceTabsView:其中一个用于MainView中的每个选项卡。
  • 物质视图和分类查看:第一个用于“åmnesinformation”,其中每个物质只有一个。第二可以有多个实例,如 “R43”, “R12” 等

我也有一些的ViewModels:

  • MainViewModel:虚拟机的的MainView。
  • SubstanceTabsViewModel:虚拟机的SubstanceTabsView,包含了一组IViewModels
  • SubstanceViewModel的,ClassificationViewModel:都实现IViewModel,是SubstanceView和ClassificationView

一些相关的XAML代码虚拟机:

这里是MainView.xaml中的tabcontrol控件

<TabControl SelectedItem="{Binding Path=SelectedTab}" ItemsSource="{Binding Path=Tabs}" > 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Header}" > 
        </TextBlock> 
        <local:CrossButton Margin="3" Padding="0" Width="12" Command="{Binding CloseCommand}"/> 
       </StackPanel> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 
     <TabControl.Resources> 
      <Style TargetType="{x:Type TabItem}"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type TabItem}"> 
          <Grid> 
           <Border 
           Name="Border" 
           Margin="0,0,-4,0" 
           Background="{Binding Path=HeaderBackground}" 
           BorderBrush="#A0A0A0" 
           BorderThickness="1,1,1,1" 
           CornerRadius="3,10,0,0" > 
            <ContentPresenter x:Name="ContentSite" 
            VerticalAlignment="Center" 
            HorizontalAlignment="Center" 
            ContentSource="Header" 
            Margin="12,2,12,2" 
            RecognizesAccessKey="True"/> 
           </Border> 
          </Grid> 
          <ControlTemplate.Triggers> 
           <Trigger Property="IsSelected" Value="True"> 
            <Setter Property="FontWeight" Value="Bold" /> 
            <Setter Property="Panel.ZIndex" Value="100" /> 
            <Setter TargetName="Border" Property="Background" Value="{Binding HeaderBackground}" /> 
            <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" /> 
           </Trigger> 
           <Trigger Property="IsEnabled" Value="False"> 
            <Setter TargetName="Border" Property="Background" Value="Yellow" /> 
            <Setter TargetName="Border" Property="BorderBrush" Value="Black" /> 
            <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" /> 
            <Setter Property="Foreground" Value="Green" /> 
           </Trigger> 
          </ControlTemplate.Triggers> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
      <DataTemplate DataType="{x:Type localViewModels:SubstanceTabsViewModel}"> 
       <localViews:SubstanceTabsView /> 
      </DataTemplate> 
      </TabControl.Resources> 

    </TabControl> 

下面是如何控制SubstanceTabsView.xaml不同视图和的ViewModels之间的连接

<TabControl SelectedItem="{Binding Path=SelectedTab}" ItemsSource="{Binding Path=Tabs}"> 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Header}" /> 
        <local:CrossButton Margin="3" Padding="0" Width="12" Command="{Binding CloseCommand}"/> 
       </StackPanel> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 
     <TabControl.Resources> 
      <DataTemplate DataType="{x:Type localViewModels:ClassificationViewModel}"> 
       <localViews:ClassificationView /> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type localViewModels:SubstanceViewModel}"> 
       <localViews:SubstanceView /> 
      </DataTemplate> 
     </TabControl.Resources> 
    </TabControl> 

下面是其控制所述第二级标签SubstanceTabsViewModel.cs的代码,对于selectedTab装定控制,用于提示一些逻辑用户约从一个未保存的标签改变:

private IViewModel selectedTab; 
    public IViewModel SelectedTab 
    { 
     get 
     { 
      return selectedTab; 
     } 
     set 
     { 
      MessageBoxResult rsltMessageBox = MessageBoxResult.Yes; 
      if (selectedTab != null && selectedTab.SaveNeeded() && selectedTab.Id != 0 && value != null && selectedTab is ClassificationViewModel) 
      { 
       rsltMessageBox = notifyUserService.Ask("Bedömning är ändrad men ej sparad vill du verkligen lämna fliken?", "Bedömning ändrad"); 
      } 
      if (rsltMessageBox == MessageBoxResult.Yes) 
      { 
       selectedTab = value; 
      } 
      OnPropertyChanged("SelectedTab"); 

     } 
    } 

    private ObservableCollection<IViewModel> tabs; 
    public ObservableCollection<IViewModel> Tabs 
    { 
     get 
     { 
      return tabs; 
     } 
     set 
     { 
      tabs = value; 
      OnPropertyChanged("Tabs"); 
     } 
    } 

有些东西我的研究,结果:如果我不这样做的notifyUserService调用(这会导致messagebox.show()),是没有问题的,只一个选项卡被选中。如果我查看TabControl的SelectedItem,它只是一个项目,它是“应该”在我的情况下。

回答

1

我终于发现有人有类似的问题,如here所述,“显示消息框会导致嵌套消息泵;这意味着几乎所有的处理都会恢复。当然,我们正在尝试更改所选项目,所以这会导致各种无序或重入问题。这类问题很难解决,我们无法在下一个版本中解决这个问题。“所以问题是在selectedItem设置器中使用MessageBox:es。

我想使用一些聪明的解决方法是在这种情况下适当的解决方案。

+0

在您的链接建议附加的行为不起作用在我的情况。仍然有同样的问题:( – Lumo 2017-07-31 10:00:20

相关问题