tabcontroller中的两个选定选项卡

时间:2014-09-23 14:32:09

标签: c# wpf xaml mvvm tabs

我遇到TabControl的问题,我管理(在某些特殊情况下)以选择两个标签页(只有一个主体显示afaik),我无法更改所选标签。

Screenshot

选定的标签有粗体标题文字。

在此图像中,“Ämnesinformation”和“R43”都被选中。

我的申请结构如下:

我有一些观点:

  • MainView:主视图包含TabControl,其中只包含图像中的一个项目。
  • SubstanceTabsView: MainView中每个标签的其中一个。
  • SubstanceView和ClassificationView:第一个用于“Ämnesinformation”,其中每个物质只有一个。第二个可以有多个实例,如“R43”,“R12”等。

我也有一些viewModels:

  • MainViewModel: MainView的VM。
  • SubstanceTabsViewModel: SubstanceTabsView的VM,包含一组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中不同视图和视图模型之间的连接

<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的setter控制一些逻辑,询问用户从未保存的选项卡进行更改:

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 个答案:

答案 0 :(得分:1)

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

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