WPF-单击按钮可以重置一些TabControl选项卡

本文关键字:TabControl 选项 单击 按钮 WPF- | 更新日期: 2023-09-27 18:24:50

我使用Caliburn.Micro作为MVVM框架,我有一个应用程序,它有一个TabControl,每个Tab都是一个ViewModel(和View),上面有几个按钮,还有一个我构建的自定义UserControl,里面也有一个按钮。所有选项卡都有相同的结构(它们使用相同的ViewModel/View)。

问题是,出于某种原因,当我单击自定义UserControl内部的按钮时,它会重置其他选项卡-内部的控件会重置为其初始值,DataGrids会被清除等。奇怪的是:

它并不总是发生,也不总是发生在所有选项卡上,即使我注释掉了UserControl按钮的Click事件中的所有内容,它也会发生(因此,仅通过引发Click事件,某些选项卡,有时所有选项卡都会无故重置)。

我读到TabControl有一个奇怪的东西,在某些情况下它不能持久化数据,但

a) 我不认为是这样,因为当在选项卡之间切换时,数据仍然很好,当我点击按钮时,它就会消失

b) 即使是同样的问题,我也不能真正使用谷歌提供的解决方案,因为Views、ViewModels和TabControl的绑定是由Caliburn完成的。Micro和我不能搞砸它是如何做到这一点的(例如,我不能像一些帖子所建议的那样,让TabControl使用一个新的属性来代替ItemSource)。

看起来它只是完全重置了整个视图,就像应用程序刚刚启动一样。当我读到TabControl的持久性问题时,人们通常认为排序设置、选择等内容会被清除,但在这种情况下,整个选项卡都会被清除——包括DataGrids的数据和其他一切我注意到它只会重新创建视图(当切换回它们的选项卡时会调用它们的构造函数),但视图后面的ViewModels不会

以前有其他人经历过这种情况吗?你做了什么

WPF-单击按钮可以重置一些TabControl选项卡

我已经搜索了几个小时,不知何故完全错过了这个解决方案:阻止TabControl重新创建其子

我真的不确定它是如何工作的,但它在切换选项卡和按下任何按钮时都会以某种方式阻止视图的重新创建。

一个解决方案可以避免使用TabItems来保存控件。相反,将TabItems保留为空,并将通常会出现在TabItems中的所有控件添加到同一个网格元素中,并将所需控件的Panel.ZIndex设置为更高。示例:

<Window x:Class="testtab.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="testtab" Height="300" Width="300"
    >
    <Grid Name="Grid1">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>          
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>     
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Content="Persistant State for UserControls" 
               Background="Blue" Foreground="Yellow"/>
        <TabControl Grid.Row="1" 
               Name="TabControl1"
               SelectionChanged="TabControl_SelectionChanged">
            <TabItem Header="Page1" />
            <TabItem Header="Page2" />
            <TabItem Header="Page3" />
        </TabControl>
        <!-- ZIndex: top=1; botton=0 -->
        <TextBox Name="b1" Grid.Row="2" Panel.ZIndex="1" Text="b1"/>
        <TextBox Name="b2" Grid.Row="2" Panel.ZIndex="0" Text="b2"/>
       <TextBox Name="b3" Grid.Row="2" Panel.ZIndex="0" Text="b3"/>     
    </Grid>
</Window>

以下是相关的事件处理程序:

void TabControl_SelectionChanged(
   object sender, 
   SelectionChangedEventArgs e)
{
    //need this if settings SelectedIndex on TabControl
    if (!IsInitialized) return; 
    switch(TabControl1.SelectedIndex) {
        case 0:
            Panel.SetZIndex(b1, 1);
            Panel.SetZIndex(b2, 0);
            Panel.SetZIndex(b3, 0);                             
            break;                  
        case 1:
            Panel.SetZIndex(b1, 0);
            Panel.SetZIndex(b2, 1);
            Panel.SetZIndex(b3, 0);                                                 
            break;
        case 2:
            Panel.SetZIndex(b1, 0);
            Panel.SetZIndex(b2, 0);
            Panel.SetZIndex(b3, 1);                                                 
            break;
    }
    e.Handled = true;
}

我手头没有任何UserControls。。。所以我们正在使用TextBox控件。。。

经过思考,您可能还需要控制每个控件的Visibility属性,在"Collapsed"answers"Visible"之间进行选择。换言之,如果控件由于未选择其选项卡而未显示,则应将其"可见性"设置为折叠或隐藏,以免干扰顶部的选项卡。