2

我为列表框控件定义了 2 个数据模板。1 个模板用于未选定状态,另一个用于选定状态(显示比未选定状态更详细的信息)。

我按照这里的例子:

http://blogs.msdn.com/b/wpfsdk/archive/2007/04/16/how-do-i-programmatically-interact-with-template-generated-elements-part-ii.aspx

关于如何从后面的代码访问 DataTemplates 中的元素。

我猜对了,但它只找到并返回 UnSelected DataTemplate 的一个元素。但是当我在 Selected DataTemplate 中搜索一个元素时,我得到一个 NullReferenceException。

我可能做错了什么?

4

2 回答 2

4

设置键盘焦点可能是您需要访问数据模板元素的原因之一。MVVM 不会解决这个问题,并且 FocusManager 不会设置键盘焦点。

于 2012-02-06T20:55:49.277 回答
1

你在做什么错?

我会说你做错了什么是试图从代码隐藏中访问 DataTemplate 中的元素。 淘气,淘气!

不开玩笑,99.9% 的时间我看到有人试图从代码中访问 DataTemplate 中的元素,这是因为他们的应用程序设计不佳,没有(或很少)绑定,根本没有视图模型。许多初学者倾向于将他们的数据直接存储在 UI 元素中,而不是使用视图模型。我认为这是因为他们的思想已经被 VB、WinForms 和 ASP.NET 的经验所破坏,而这些都是“正常”的做法。使用视图模型和绑定数据而不是将它们存储在 UI 元素中的理由有上千个。在线查找“模型视图视图模型”以获取更多详细信息。

现在回答你的问题:

任何给定的 ListBoxItem 一次只能有一个 DataTemplate。这是因为它的 ContentPresenter 只有一个 ContentTemplate 属性,并且该属性不能有两个不同的值。

因此,ListBoxItem 下的可视化树将始终从一个特定模板生成,而不是多个模板的组合。如果您更改 ListBox 的 ItemTemplate 或以其他方式更新 ListBoxItem.ContentTemplate,则旧模板生成的可视化树将被丢弃并构建一个新模板。

再说一遍:如果你改变数据模板,旧数据模板产生的可视化树将被丢弃,并建立一个新的可视化树

您可以在给定的 ListBoxItem 上定义和使用一百个数据模板,但一次只能为其实例化一个可视化树。这些是作为可视化树的一部分实际存在的唯一元素。所有其他模板仅作为模板存在 - 没有为它们创建实际元素。

换句话说:问如何在同一个控件上由两个不同模板实例化的两个不同的可视化树中找到元素是没有意义的,因为一个控件不能同时激活两个不同的模板。

希望这可以为您解决问题。

最后的建议:阅读 MVVM,并停止尝试尽快访问 DataTemplates 中的元素。但是,如果您认为您可能属于确实有正当理由访问模板内元素的 0.1%,请写回您想要这样做的实际原因,也许我可以提供进一步的指导。

于 2010-06-13T08:15:20.337 回答