如果你使用WPF,请使用ContainerControl
或ContentPresenter
。
一般来说,“切换可见性”不是一个很好的方法。它会强制UI创建所有对象,即使那些不可见的对象,还要处理它们的数据和事件等等。
而且你需要手动切换它们。
在WPF中,提供了许多可以节省此过程的机制。其中有些更加智能,有些则不然。
WPF中最基本的机制之一是Control
和其Template
属性。你可以用单个Control
替换整个Grid+Contents+SwitchingVisibility的想法,并切换它的Template
:
<Window.Resources>
<ControlTemplate x:Key="panel1"> ..carrots.. </ControlTemplate>
<ControlTemplate x:Key="panel2"> ..cucubers.. </ControlTemplate>
<ControlTemplate x:Key="panel3"> ..donkey.. </ControlTemplate>
...
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Control x:Name="foo" />
</Grid>
现在,如果你获取foo
并设置它的.Template
为panel1
,那么"carrots"就会显示出来。如果你将它设置为panel3
,则是"donkeys"。依此类推。
虽然这很强大,但由于其他一些我不打算涉及的原因,它不会真正方便。有许多书籍和教程深入解释了模板。此外,这个机制并不是为这样的任务而设计的。它是最基本的机制,如果你想在WPF中工作,了解这一点是很好的,但这里有更合适的机制。
接下来第二个最强大且仍然基本的机制是ContentControl/ContentPresenter
。它们几乎以相同的方式工作(实际上CC在内部使用CP),所以我会跳过它。
ContentControl是一个聪明的控件,它知道如何根据你要呈现的数据自动选择正确的模板。
因此:
<Window.Resources>
<DataTemplate DataType="CarrotData"> ..carrots.. </..>
<DataTemplate DataType="CucumberData"> ..cucubers.. </..>
<DataTemplate DataType="DonkeyData"> ..donkey.. </..>
...
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ContentControl x:Name="foo" Content="{Binding ..}" />
</Grid>
请注意从“ControlTemplate”更改为“DataTemplate”。
现在,有了这个设置,您甚至不需要手动切换模板。您只需获取“foo”,将其内容设置为以下之一:
- 一个包含与胡萝卜相关数据的CarrotData对象
- 一个包含黄瓜相关数据的CucumberData对象
- 一个包含驴子相关数据的DonkeyData对象
一旦设置要显示的数据(即foo.Content = carrots [5]
),ContentControl将选择要显示的相关模板。
您可以将Content
属性绑定到几乎任何东西。如果您有一个包含胡萝卜/驴子并具有属性CurrentThing
的数据类,您可以将其绑定到ContentControll,ContentControll会自动随着对CurrentThing的更改而切换视图。
那是基础知识。我试图简要介绍的几乎任何地方都有更多内容。现在,离开ControlTemplates。阅读有关DataTemplates和Bindings的信息。阅读ContentPresenter(显示1个项目的1个模板)和ItemsControl(显示N个项目+模板)。然后,稍微了解MVVM模式。
您很快就会发现,“将所有内容放入一个网格”和“切换可见性”是一种奇怪的方式。
但是,如果我不提到所有的成本,那就不公平了。广泛使用模板和绑定会使您的应用程序比手动完成的应用程序稍慢一些。但通常,手动完成并没有真正值得去做。