【问题标题】:XAML: Under the HoodXAML:引擎盖下
【发布时间】:2012-08-03 19:34:30
【问题描述】:

好吧,我必须承认,有时 XAML 对我来说还是有点神秘。问题是,我总是喜欢通过 C# 代码进行调试(在其中设置很多断点)来了解“正在发生什么”和“它是如何发生的”。但是对于声明性 XAML 语法,这不是一个选项。我想你会同意使用 XAML,或者更准确地说,使用/理解一些现有的 XAML 代码,你必须“已经知道”XAML 声明是如何工作的。您无法知道/学习调查应用程序代码执行的事情。因此,我非常有兴趣从内到外地查看 XAML,尽可能详细。我不是在谈论“学习”XAML,我知道基本的东西。也许我可以提供一些例子来澄清我正在寻找的东西 -

  • 与 C# 代码相比,当我们在 XMAL 中使用对象时如何实例化它们?它们是否存储在托管堆中?与 C# 代码实例化对象的方式相同吗?
  • 在使用标记扩展语法进行数据/命令绑定时如何设置属性?
  • 当 INotifyPropertyChanged 类型的任何属性更新时,XAML 语法中的绑定实例如何更新自身?它究竟是如何在第一时间得到通知的,以及由谁通知?
  • 可以通过定义 Typed DataTemplate 在运行时将视图模型设置为视图的 DataContext,例如 -
    <DataTemplate DataType="{x:Type viewmodels:AccountsViewModel}">
    <views:Accounts/>
    </DataTemplate>

    它实际上是如何发生的?除了在逻辑树上向上搜索 DataContext 属性之外,设置 DataContext 的规则是什么?
  • 如何在运行时处理/解析整个模板内容(DataTemplate、ControlTemplate 和 ItemsPanelTemplate)。
  • 等。等等等等。

因此,如果您在 XAML 方面表现出色/经验丰富/专家,您会建议什么(链接、文章、博客文章、书籍等)作为参考,以帮助更清楚和更深入地了解 XAML 如何“在幕后”工作?提前致谢。

【问题讨论】:

  • 你提出了一些有趣的问题,但这是一个非常广泛的问题,不太可能得到明确的答案——这使得它不太适合 StackOverflow。但是,可能有助于您理解的一点是,XAML 是构成 UI 的对象的序列化。当您将&lt;Button... 放入您的xaml 时,这将在运行时产生一个Button 类的实例,此时创建UI。因此,“调试 Xaml”是没有意义的,因为 Xaml 没有被执行(它不是真正的“代码”并且不包含指令)。
  • 请不要关闭问题。试着理解所有这些要点都不是我的问题。这些仅代表有关我正在寻找的参考类型的提示。我唯一的问题是最后一段的最后一个问题——“……你有什么建议……?”
  • 最有可能:Google、MSDN 和 WPF 圣经 (amazon.com/WPF-4-Unleashed-Adam-Nathan/dp/0672331195)。
  • @DanPuzey:感谢 Dan 的意见。我对“通过 XAML 进行调试”主题也有同样的猜测。我读过 Nathan 的 WPF-4-Unleashed (amazon.com/WPF-4-Unleashed-Adam-Nathan/dp/0672331195)。它没有多大帮助。 C# 2010 (apress.com/9781430272052) 中的 MacDonald 的 Pro WPF 好很多。但是,当您单独考虑 XAML 时,这似乎并不令人满意。
  • 再仔细看看“WPF 4 Unleashed”的“XAML Demystified”一章。在我看来,它解释了很多。

标签: c# wpf xaml


【解决方案1】:

大多数情况可以通过不将 XAML 视为一种真正的编程语言来解释,更像是一种声明性语言。你在 xaml 中所做的一切,也可以在 C# 中进行,事实上这就是正在发生的事情。

与 C# 代码相比,当我们使用对象时如何实例化它们 在 XMAL 中?它们是否存储在托管堆中?与 C# 相同的方式 代码实例化的对象?

是的,因为它们只是 c# 对象。大多数资源都存储在休眠状态,我记得某处膨胀这个词。转换器或其他“直接”c# 对象在需要时创建。这里重要的是这些资源通常是共享的,因此它们只会被创建一次。

使用标记扩展语法进行数据/命令绑定时如何设置属性?

这又取决于您在何处使用标记扩展。在一个风格?在模板中?在像窗口这样的实例化用户控件中?通常在您真正需要它们时对它们进行评估。当膨胀的样式存储在实际的资源字典中时,评估它们是没有意义的。当您实际在对象上使用样式时,它们会得到评估。

当 INotifyPropertyChanged 类型的任何属性被更新时,如何 XAML 语法中的绑定实例会更新自身吗?如何 确切地说,它是在第一时间得到通知的,以及由谁通知的?

通过绑定引擎。 WPF 检查您的 DataContext 是否继承了 INotifyPropertyChanged 接口,附加到该接口提供的事件并侦听任何更改。如果引发此类事件,绑定引擎将再次调用 getter。

它实际上是如何发生的?设置DataContext的规则是什么 除了向上搜索 DataContext 属性 逻辑树?

简而言之:没有其他。 Datacontext 只是一个继承的附加属性。如果您不在子控件上重新设置它,它将采用父控件的值,直到它到达根。唯一的例外是ContentControlsContentPresenter,它们不会继承 DataContext,但会根据内容更改它们。所以这些控件在默认情况下总是将 Content 作为它们的 DataContext。

如何在运行时处理/解析整个模板内容(DataTemplate、ControlTemplate 和 ItemsPanelTemplate)。

简单地说:每当 WPF 找到一个非 ui 对象时,它都会尝试为给定类型找到一个 DataTemplate。以 ItemsControl 为例:您可以绑定MyClass 的列表;除非您提供显式 DataTemplate 或 DataTemplateSelector,否则它将向上搜索资源树以查找隐式样式。再次记住,这在 XAML 中已经没有发生,而是在从 xaml 生成的 C# 对象上发生。

是否可以通过任何方式(目前或不久的将来)进行调试 通过 XAML 代码?

您认为如何调试未执行但在编译时评估的内容?

请不要认为这是 100% 正确的。多年来,这是我收集的有关 XAML 和使用的信息。如果您有任何更正或发现明显错误的地方。请告诉我,我们都在这里学习,我总是学习关于我使用的东西的新东西:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2018-03-03
    • 2010-11-03
    相关资源
    最近更新 更多