【问题标题】:XAML without the .xaml.cs code behind files没有 .xaml.cs 代码的 XAML 文件
【发布时间】:2010-12-22 22:26:42
【问题描述】:

我正在使用带有模型-视图-视图模型模式的 WPF。因此,我的文件后面的代码 (.xaml.cs) 都是空的,除了调用 InitializeComponent 的构造函数。因此,对于每个 .xaml 文件,我都有一个匹配的、无用的 .xaml.cs 文件。

我发誓我在某处读到过,如果文件后面的代码除了构造函数之外是空的,那么有一种方法可以从项目中完全删除该文件。网上搜了下,似乎合适的方法是使用'x:Subclass'属性:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    x:Class="MyNamespace.MyClass"
    x:Subclass="UserControl"
    d:DesignWidth="700" d:DesignHeight="500">

这会在生成的 .g.cs 文件中执行以下操作:

  1. 删除 MyClass 上的“部分”类修饰符。
  2. 将“UserControl”类添加到其子类列表中。

看起来很完美。实际上,如果您在构建中仍然有 .xaml.cs 文件,则由于缺少部分文件而不再编译 - 所以我认为这一定是正确的。但是,如果我从构建中删除多余的文件并运行,控件不会正确初始化(它是空白的)。我想这是因为 InitializeComponent() 没有被调用。我看到 InitializeComponent 不是虚拟的,所以基类似乎没有办法调用它(没有使用反射)。

我错过了什么吗?

谢谢!

埃里克

【问题讨论】:

    标签: wpf xaml mvvm code-behind


    【解决方案1】:

    作为另一种选择,如果您不想一直使用 DataTemplates,这里是 UserControls 的另一种方法:

    使用 x:Code 属性在 XAML 中嵌入构造函数调用:

    <x:Code><![CDATA[ public MyClass() { InitializeComponent(); }]]></x:Code>
    

    埃里克

    【讨论】:

    • 这是一个非常巧妙的解决方案。
    • 甜蜜。谁会想到这一点?
    • 好吧...我赞成这个,因为它非常聪明,但是在您的 XAML 文件中包含这种 CDATA 代码感觉有些不对...就像其他人问的那样一个类似的话题,为什么我们要费力地删除空的代码隐藏文件?他们不介意,几乎看不到他们坐在那里。不过,我喜欢你的创造力:-)
    • 我们这里有一条规则,唯一可以进入 CDATA 的是带有 InitializeComponent() 的构造函数。其他任何东西,它应该在代码后面。
    • 至于为什么要摆脱代码隐藏——我想这是因为我是一个纯粹主义者。如果我要使用 Model-View-ViewModel,我需要另一个文件:Model-View-CodeBehind-ViewModel。我正在学习喜欢 MVVM,但我尽量避免 V 和 VM 之间的任何代码隐藏魔法。另外,作为一名程序员,我需要知道是否有魔法。如果我没有看到代码隐藏文件,我知道没有。
    【解决方案2】:

    如果您关注Josh Smith's MVVM article,他将 DataTemplates 用于视图而不是用户控件。如果您将 DataTemplates 放入 ResourceDictionaries,它们根本没有代码隐藏。如果您不使用用户控件的代码隐藏,这是否意味着您可以使用 DataTemplate 方法?如果你这样做了,WPF 会帮你把你的 View 绑定到你的 ViewModel。

    【讨论】:

    • 谢谢斯科特。这绝对是一种更好的方法。
    • +1 我也用这种方式。它的效果非常好,几乎就像魔术一样。
    • 注意: 在 WPF 中可用,但在 Silverlight 中不可用。
    【解决方案3】:

    我与 PDC 的一位 Windows 客户端团队成员就此进行了讨论,现在被告知没有官方支持的方法可以完全消除文件隐藏代码。如您所见,您可以编译它,但从未调用过InitializeComponent(),因此无法正确设置控件。

    x:Subclass attribute“主要用于不支持部分类声明的语言。”它不打算允许这种行为(不幸的是)。

    【讨论】:

      【解决方案4】:

      如果您使用的是 caliburn micro,您可以有效地删除 .xaml.cs,框架会负责初始化(即,如果您使用视图模型方法)。

      这是在讨论https://caliburnmicro.codeplex.com/discussions/444250

      【讨论】:

        【解决方案5】:

        出于纯粹的好奇,您是否尝试过使用它:

        x:Subclass="Control"
        

        默认情况下,用户控件需要 InitializeComponent() 调用,但事实上的标准控件不需要。我很想看看这是否有效。

        -道格

        【讨论】:

        • 刚刚试过这个。它没有改变行为。如果没有调用 InitializeComponent(),控件是空白的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多