2014-09-23 139 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