WPF中的设计模式

3
我正在制作我的第一个WPF应用程序,所以这个问题可能看起来相当奇怪。我一直在阅读有关MVVM的内容,到目前为止,它对我来说很有意义。然而,我不明白的是如何分离所有的XAML。
我的意思是:我假设您不会将所有内容都放在MainWindow.xaml中,而是根据将要使用的内容折叠控件。我认为您希望有一个容器,包含其他文件的xaml。这样正确吗?
您如何分离XAML,使之不仅仅是一个混杂在一个文件中的东西?

我认为你的问题与MVVM模式无关,而更多地涉及到ResourceDictionaries - nik
3个回答

6
如何将XAML分离,使其不再是一个文件中的所有内容混合在一起?
有许多方法,包括创建单独的UserControlCustomControlPageWindow
例如,如果您想从您的MainWindow.xaml中提取一些XAML,您可以创建一个UserControl(右键单击项目,添加新项目...用户控件(WPF))称为MyUserControl.xaml
<UserControl x:Class="WpfApplication1.MyUserControl"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid>
        <TextBlock>This is from a different XAML file.</TextBlock>
    </Grid>
</UserControl>

然后在你的 MainWindow.xaml 中使用这个控件,像这样:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:myControls="clr-namespace:WpfApplication1">
    <Grid>
        <myControls:MyUserControl/>
    </Grid>
</Window>

请注意,您需要添加对您的UserControl命名空间的引用。
xmlns:myControls="clr-namespace:WpfApplication1"

当用户与我的应用程序交互时,我应该在MainWindow的内容中切换折叠/可见的各种控件吗? - Justin
2
@Justin 偏爱使用数据模板,可以参考我的回答。 - Kirk Broadhurst

2
我同意Kevin关于UserControl和Window的回答,所以我只回答后续问题:
“那么当用户与我的应用程序交互时,我应该在我的MainWindow内容中切换各种已折叠/可见的控件吗?”
这是一个有效的选项。如果你正在处理一个大型应用程序,可能会变得混乱。
我使用的其他选项有:
在代码后台中切换视图;例如,在单击事件中,您可以像在WinForms中一样添加和删除页面元素。这不是纯粹的MVVM,有些人会对此进行批评,但我认为MVVM是一种工具,而不是一种信仰。
在ViewModel中提供Views作为属性,并从父View绑定到它们。我不知道这是否是纯粹的MVVM,当您需要根据复杂条件动态创建Views时,这很好,但可能会变得复杂。
使用DataTemplates,它们本质上是基于提供的数据类型确定要使用的View的规则。因此,如果数据是Address(或AddressViewModel),则使用AddressView。如果数据是CustomerViewModel,则使用CustomerView。等等。
在我看来,DataTemplates是首选模式-清晰、易于维护和一个很好的标准。查看绑定如何工作的DataTemplate是微不足道的,而我给出的其他两个选项可能会导致错误的人编写混乱的代码。
MSDN有一个关于WPF中数据模板的不错页面DataTemplates in WPF

1

使用Caliburn框架时,您可以使用较小的视图和ViewModel组合应用程序,并具有将所有这些较小视图绑定在一起的外壳。外壳将同时显示一个或多个视图,具体取决于您希望应用程序如何运行。与上述模式不同的好处是,您不需要在其他地方硬编码View/UserControl的名称,而只需创建ContentControl并将其绑定到正确的ViewModel属性,Caliburn将按约定为您找到正确的View。

假设您有一个ShellViewModel和一个ShellView,它只是一个空窗口,以及另一个View/ViewModel,在其中您希望在某个时候在外壳中显示。您不再需要在任何地方实例化视图,只需使用POCO ViewModel对象即可完成工作:

public class ShellViewModel : Screen
{
   public ChildViewModel Child { get; set; }

   public void SomeAction()
   {
       Child = new ChildViewModel(); //Or inject using factory, IoC, etc.
   }
}

public class ShellView : Window
{
}

<Window x:Class="WpfApplication1.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:cal="http://www.caliburnproject.org">
    <Grid>
        <ContentControl cal:View.Model="{Binding Child}" />
    </Grid>
</Window>

有趣,我会去看看。 - Justin

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