WPF中TabControl的UI持久化

4
我遇到了一个看起来很简单但实际上却很困难的问题。
假设你有一个TabControl,绑定到ViewModels的itemsource,并使用DataTemplate显示项目。现在假设DataTemplate由一个具有两列和Grid Splitter调整列大小的网格组成。
问题是,如果你在一个选项卡上调整列的大小,并切换到另一个选项卡,那么列也会被调整大小。这是因为TabControl在所有选项卡之间共享DataTemplate。这种缺乏UI持久性应用于模板的所有元素,这可能会导致令人沮丧的体验,当各种UI组件被调整时。另一个例子是DataGrid中的滚动位置(在选项卡上)。如果一个具有更多行的DataGrid被滚动到底部,那么具有少量项目的DataGrid将被滚动出视图(只有一行可见)。除此之外,如果TabControl在多个DataTemplates中定义了各种项,则在不同类型的项之间切换时,视图将被重置。我可以理解这种方法节省资源,但结果功能似乎与预期的UI行为相矛盾。
因此,我想知道是否有解决方案/解决方法,因为我确信其他人也遇到过这个问题。我注意到其他论坛上有一些类似的问题,但没有真正的解决方案。其中一个是使用AdornerDecorator,但当与DataTemplate一起使用时似乎不起作用。我不喜欢将所有UI属性(如列宽度、滚动位置)绑定到我的ViewModels上,事实上,我尝试了这个简单的GridSplitter示例,但我没有成功使其工作。ColumnDefinitions的宽度不一定受到网格分隔符的影响。无论如何,如果有一个通用的解决方案就好了。有什么想法吗?
如果我放弃TabControl并使用ItemsControl,我会遇到类似的问题吗?是否可能修改TabControl样式,使其不在选项卡之间共享ContentPresenter?
1个回答

3

我已经断断续续地处理这个问题有一段时间了。最终,我没有尝试修复/修改TabControl,而是重新创建了它的功能。这实际上效果非常好。我使用ListBox(选项卡标题)和ItemsControl制作了类似于选项卡的控件。关键是将ItemsControl的ItemsPanelTemplate设置为Grid。稍微进行一些样式设置,并使用DataTrigger来管理项目的可见性,就可以轻松完成。它完美地工作,每个“选项卡”都是一个独特的对象,并保留了所有的UI状态,如滚动位置、选择、列宽等。这种解决方案可能会出现什么缺点或问题吗?

       <DockPanel>
            <ListBox
                DockPanel.Dock="Top"
                ItemsSource="{Binding Tabs}"
                SelectedItem="{Binding SelectedTab}"
                ItemContainerStyle="{StaticResource ImitateTabControlStyle}">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel
                            Orientation="Horizontal">
                        </StackPanel>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>

                <ListBox.ItemTemplate>
                    <DataTemplate>                            
                        <StackPanel 
                            Margin="2,2,2,0"
                            Orientation="Horizontal" >
                            <TextBlock 
                                Margin="4,0" FontWeight="Bold"
                                Padding="2"
                                VerticalAlignment="Center" HorizontalAlignment="Left"
                                Text="{Binding Name}" >
                            </TextBlock>
                            <Button
                                Margin="4,0"
                                Command="{Binding CloseCommand}">
                                <Image Source="/TERM;component/Images/Symbol-Delete.png" MaxHeight="20"/>
                            </Button>
                        </StackPanel>                            
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <ItemsControl    
                ItemsSource="{Binding Tabs}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <ContentControl                                
                            Content="{Binding}">
                            <ContentControl.Style>
                                <Style>
                                    <Style.Triggers>
                                        <DataTrigger
                                            Binding="{Binding IsSelected}" Value="False">
                                            <Setter Property="ContentControl.Visibility" Value="Hidden" />                                                
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </ContentControl.Style>
                        </ContentControl>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>                
        </DockPanel>

你能提供“ImitateTabControlStyle”资源以便测试吗?听起来不错。 - Kishore Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接