【问题标题】:Design pattern in WPFWPF 中的设计模式
【发布时间】:2012-07-08 22:28:56
【问题描述】:

我正在制作我的第一个 WPF 应用程序,所以这个问题可能看起来很奇怪。我一直在阅读有关 MVVM 的内容,到目前为止它对我来说很有意义。但是,我不明白的是分离所有 XAML。

我的意思是:我假设您不会将所有内容都放在 MainWindow.xaml 中,而只是根据将要使用的内容折叠控件。我想你会想要一个包含其他文件的 xaml 的容器。它是否正确?

您如何将 XAML 分离出来,使其不仅仅是一个文件中所有内容的混搭?

【问题讨论】:

标签: c# .net wpf mvvm


【解决方案1】:

您如何将 XAML 分离出来,使其不仅仅是一个文件中所有内容的混搭?

有很多方法,包括创建一个单独的UserControl, CustomControlPage or Window

例如,如果您想从您的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 首选模式是使用 DataTemplates,请参阅我的回答。
【解决方案2】:

我同意 Kevin 关于 UserControl 和 Window 的回答,所以我将只解决后续问题:

所以当用户与我的应用程序交互时,我应该在 MainWindow 内容中折叠/可见的各种控件之间切换?

这是一个有效的选项。如果您使用的是大型应用程序,它可能会变得混乱。

我使用的其他选项是

  • 在后面的代码中切换视图;即在单击事件中,您可以像在 WinForms 中那样在页面中添加和删除元素。这不是纯粹的 MVVM,有些人会跳入你的喉咙,但我相信 MVVM 是一种工具,而不是一种宗教。
  • 在您的 ViewModel 中提供视图作为属性,并从您的父视图绑定到它们。我不知道这是否是纯 MVVM,当您需要根据复杂条件动态创建视图时很好,但它可能会变得复杂
  • 使用 DataTemplates,它本质上是根据提供的数据类型确定要使用的视图的规则。因此,如果数据是Address(或AddressViewModel),请使用AddressView。如果数据是CustomerViewModel,请使用CustomerView。等等。

在我看来,DataTemplates 是首选模式 - 干净、易于维护并且是一个不错的标准。去 DataTemplate 看看绑定是如何工作的很简单,而我给出的其他两个选项可能会导致意大利面条代码落入坏人手中。

MSDN 在DataTemplates in WPF 上有一个不错的页面。

【讨论】:

    【解决方案3】:

    使用 Caliburn 框架时,您可以使用较小的 View 和 ViewModel 组成您的应用程序,并拥有一个将所有这些较小的视图绑定在一起的 shell。 shell 将同时显示一个或多个视图,具体取决于您希望应用程序的行为方式。这样做的好处 - 与上面提到的模式不同,您在其他地方硬编码 View/UserControl 的名称 - 是您只需创建一个 ContentControl 并将其绑定到正确的 ViewModel 属性,Caliburn 将通过以下方式为您找到正确的 View习俗。

    假设您有一个 ShellViewModel 和一个 ShellView,它只是一个空窗口,还有另一个 View/ViewModel,您希望在其中一次显示在您的 shell 中。您不再需要在任何地方实例化您的视图,只需使用 POCO ViewModels 对象按自己的方式工作:

    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>
    

    【讨论】:

    • 有意思,我去看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多