2010-09-30 50 views
0

好的...这里有两个人。 (中排序。实际上可能只是一个,那就是我希望反正。)修改或“调整”现有的TreeViewItem控件模板?

首先,更普遍的,是有可能的目标,仅通过XAML,在控制的模板命名的项目?例如,如果控件的模板有一个名为'PART_Foo'的ContentPresenter,并且我们想通过纯样式将该特定项目上的Horizo​​ntalAlignment设置为'Stretch',是否可以完成?我知道我们可以在子类的OnApplyTemplate覆盖中做到这一点,我们通过名称显式地搜索控件,然后在代码中设置属性,但是我们希望只使用仅限XAML的解决方案,因此我们可以通过样式严格执行此操作而不是子类,除了特定的用例场景之外,它们大多不鼓励使用。

另外,我们做不是想要手动指定控件的模板,因为我们希望当前主题确定该模板是什么,从而确定控件是如何显示的。我们只想说'在主题选择的任何模板中,如果有一个名为'foo'的部分,通过纯样式设置该属性。如果找不到那个名字的部分,什么也不要做!

对仅使用XAML方法的期望更多的是因为第二部分,我们将目标定位为生成的容器对象,而不是控件本身,意味着它不会是直接的子类,因为我们会必须用ItemcontainerGenerators等来解决这个问题,这对$$是一个真正的痛苦,特别是当ItemsControl被虚拟化时。

对于具体情况,我们的最终目标是在TreeView的TreeViewItem模板中选出名为'Bd'的边框,并将其附加属性'Grid.ColumnSpan'设置为'2'而不是默认值'1'。而已!它令我惊讶的是,如果没有手动替换整个TreeViewItem的模板或使用基于代码隐藏的解决方案,看起来如此简单似乎几乎不可能。

+0

顺便说一句,这是我们想避免不得不做的只是改变一个臭味的财产! http://msdn.microsoft.com/en-us/library/ms788727.aspx – MarqueIV 2010-09-30 04:26:57

回答

0

不,这是不可能的,只能使用XAML。你至少必须为此写一个附加属性(你可以在XAML中使用)。只有在运行时没有任何控件正在创建时才会有效,因为它发生在虚拟化列表中。它看起来像这样:c:TemplateHelper.ReplaceStretchForTemplateItemName="PART_Foo"。在更改后的处理程序中,您可以使用VisualTreeHelper来遍历该控件的可视子树,然后查找该名称并应用所需的任何内容。

修改这样的模板是有缺陷的,并且被认为是不好的做法。非常有利的是,有一个主题,或者将来会没有“Part_Foo”,或者“Part_Foo”与您预期的完全不同。主题和ControlTemplates可能会更改。随着Microsoft更新其操作系统,新主题将出现(并自动应用于您的应用程序),并且如果您支持自定义主题,则设计者可能会想出不同的主题。

你可能会认为这是ControlTemplates的一个缺点,它在某种程度上是它的缺点。但是,然后再次尝试在Windows窗体(或这个星球上的任何其他UI框架)中定制控件... 只是,当习惯了WPF的巨大可靠性时,它很难接受限制,在这种情况下,这是有限的。

+0

我很好的目标控制可能会或可能不会在那里,因为唯一的其他选项,完全取代TreeViewItem的控制模板无论如何,都可以控制主题的能力!如果我们将风格放置在本地资源中,它会覆盖主题,如果我们将它放在可以为主题的地方,这可能会破坏我们的设计,因为不保证儿童首先被拉伸。唯一的好处是TreeViewItem的主题可能性很小,因为唯一的可视化是按钮和背景突出显示。其他一切都与位置有关。 – MarqueIV 2010-09-30 19:21:03

+1

我仍然不能相信TreeView上没有“全行选择”选项,并且您必须通过所有这些箍来创建它!疯!!有一件事,虽然......我没有看到附加属性,但没有看到如何使用基于容器的项目控件。我的意思是你必须在容器被其数据源驱动创建容器时设置属性,而不仅仅是当你在控件本身设置属性时,所以你就回到了子类的噩梦。 – MarqueIV 2010-09-30 19:21:43

+0

您是否尝试过在ItemsContainerStyle中设置该属性?我会假设它应该在创建TreeViewItem时应用。当您启用虚拟化时,您可能会遇到一些问题。 – bitbonk 2010-10-01 07:51:17