C# TabControl模板的单独控件实例。x:Shared=";假;重新创建控件

C# TabControl模板的单独控件实例。x:Shared=";假;重新创建控件,c#,wpf,xaml,C#,Wpf,Xaml,该控件具有,但它似乎在选项卡索引更改时重新创建控件。我可以防止这种情况并保持控制吗 代码隐藏 public partial class MainWindow : Window { ObservableCollection<string> Tabs = new ObservableCollection<string>(); public MainWindow() { InitializeComponent();

该控件具有,但它似乎在选项卡索引更改时重新创建控件。我可以防止这种情况并保持控制吗


代码隐藏

public partial class MainWindow : Window
{
    ObservableCollection<string> Tabs = new ObservableCollection<string>();
    public MainWindow()
    {
        InitializeComponent();
        Tabs = new ObservableCollection<string>();
        Tabs.Add("Tab1");
        Tabs.Add("Tab2");

        MyTabControl.ItemsSource = Tabs;
    }       
}
public partial class MainWindow : Window
{
    ObservableCollection<Thing> Tabs = new ObservableCollection<Thing>();
    public MainWindow()
    {
        InitializeComponent();
        Tabs = new ObservableCollection<Thing>();
        Tabs.Add(new Thing("Tab1"));
        Tabs.Add(new Thing("Tab2"));

        MyTabControl.ItemsSource = Tabs;
    }       
}

class Thing
{
    public Thing(string name)
    {
        Header = name;
    }
    public string Header { get; set; }
    public TextBox RealControl { get; set; } = new TextBox();
}
公共部分类主窗口:窗口
{
ObservableCollection选项卡=新的ObservableCollection();
公共主窗口()
{
初始化组件();
Tabs=新的ObservableCollection();
表1.添加(“表1”);
表2.添加(“表2”);
MyTabControl.ItemsSource=选项卡;
}       
}

解决方法。。。现在似乎还有效

<TabControl Name="MyTabControl">
    <TabControl.Resources>
        <DataTemplate x:Key="MyTemplate">
            <ContentControl Content="{Binding RealControl}"></ContentControl>
        </DataTemplate>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="ContentTemplate" Value="{StaticResource MyTemplate}"/>
            <Setter Property="Header" Value="{Binding Header}"/>
        </Style>
    </TabControl.Resources>        
</TabControl>

代码隐藏

public partial class MainWindow : Window
{
    ObservableCollection<string> Tabs = new ObservableCollection<string>();
    public MainWindow()
    {
        InitializeComponent();
        Tabs = new ObservableCollection<string>();
        Tabs.Add("Tab1");
        Tabs.Add("Tab2");

        MyTabControl.ItemsSource = Tabs;
    }       
}
public partial class MainWindow : Window
{
    ObservableCollection<Thing> Tabs = new ObservableCollection<Thing>();
    public MainWindow()
    {
        InitializeComponent();
        Tabs = new ObservableCollection<Thing>();
        Tabs.Add(new Thing("Tab1"));
        Tabs.Add(new Thing("Tab2"));

        MyTabControl.ItemsSource = Tabs;
    }       
}

class Thing
{
    public Thing(string name)
    {
        Header = name;
    }
    public string Header { get; set; }
    public TextBox RealControl { get; set; } = new TextBox();
}
公共部分类主窗口:窗口
{
ObservableCollection选项卡=新的ObservableCollection();
公共主窗口()
{
初始化组件();
Tabs=新的ObservableCollection();
添加(新事物(“Tab1”);
添加(新事物(“Tab2”);
MyTabControl.ItemsSource=选项卡;
}       
}
阶级事务
{
公共事物(字符串名称)
{
标题=名称;
}
公共字符串头{get;set;}
public TextBox RealControl{get;set;}=new TextBox();
}

当您使用设置为
False
x:Shared
属性时,每次切换选项卡时,将从数据模板创建选项卡项内容中的新控件。这意味着所有未以任何方式保存的状态(如绑定到视图模型)都将丢失。由于未在
文本框
上存储
文本
属性的值,因此一旦切换选项卡,它将丢失,因为将创建一个新的
文本框
,其属性具有默认值

您可以通过创建一个项类型来验证这一点,该项类型具有存储
文本框中文本值的属性。然后将
Text
绑定到此属性,并确保该属性实际上是通过以下方式更新的:例如,在键入文本后失去焦点(
LostFocus
TextBox
的默认
UpdateSourceTrigger
)。当分别切换每个选项卡的选项卡时,您将看到该值通过绑定恢复。这是因为新创建了
TextBox
控件,但是绑定将从存储其状态的视图模型中更新
Text
属性

我可以防止这种情况并保持控制吗

你有多种选择

  • 如果使用
    x:Shared=False
    ,则必须自己保存视图状态,例如通过绑定到视图模型
  • 不要使用
    x:Shared
    属性,因为
    TabControl
    将更改选项卡的
    DataContext
    ,因此控件将被重用,并且只更新绑定的数据
  • 考虑不使用
    选项卡控件,而只使用用户控件,如果数据上下文始终相同,则可以在该控件中更改数据上下文

但这只是为了提问。我不使用简单的文本框作为模板。模板将非常复杂,保存/恢复控件的所有状态将非常困难。我的意思是,即使对于文本框,仅仅保存/恢复文本是不够的;对于光标位置、滚动位置、选择等,我必须这样做。因此,WPF中没有办法只保留创建的控件,这样我就不必在每次索引更改时保存/恢复内容?如果我不使用x:Shared=False,则所有选项卡都共享内容。我必须使用绑定之类的东西来保存/恢复内容,所以基本上是相同的问题。我搜索这个的原因首先是为了避免这种情况,并在每个选项卡中保留单独的控件。@DamnVegetables好的,现在我明白了你背后的原因。然而,我认为你将不得不处理其中之一。因此,要么创建多个控件实例,在这些实例中必须跟踪控件状态,要么将数据与视图模型同步,在我看来,这是最好的方法,并且清除MVVM。如果没有干净的方法以本机方式执行,我将把控件保留在绑定项本身中。因为似乎没有办法,我试了一下,似乎奏效了。我将把它附加到原始问题中。如果这些都应该是具有相同状态的同一控件,那么在一个tabcontrol中有多个控件又有什么意义呢?这是一个控制。