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中有多个控件又有什么意义呢?这是一个控制。