WPF SubControl(如TextBlock)不使用TemplateSelector从窗口inheritanceStyle
我需要帮助,因为我不明白为什么来自datatemplate的控件不会inheritance窗口资源中定义的样式。 可能有解决方法吗?
如果有人能给我一个解决方案,我会非常感激,因为我花了很多时间找到一些东西。
特此我的例子。 例如,horrizontal模板中的Texblock不对齐:
Udapte:我添加了背景颜色。 样式应用于标签,但不应用于由datatemplate定义的totextblock和textbox。
**** using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Reflection; namespace WpfApplication3 { public class TemplateSelector : DataTemplateSelector { public DataTemplate DataTemplateH { get; set; } public DataTemplate DataTemplateV { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { string s = (string)item; if (s == "H") return DataTemplateH; if (s == "V") return DataTemplateV; return base.SelectTemplate(item, container); } } }
我刚刚尝试了一些简单的演示,是的答案是你不能将模板外部某处定义的默认样式应用到模板内的某些TextBlock(包括DataTemplate和ControlTemplate)。 这不会发生在其他控件上,例如Label,TextBox(尽管你也说过Style不适用于TextBox,但我尝试过它,实际上并非如此)。
要解决此问题,最好的方法是为TextBlock明确设置样式,如下所示:
请注意,正如我所说,只有模板内的TextBlocks(DataTemplate和ControlTemplate)才需要它。
代码看起来相当荒谬,但它实际上是有效的,没有这样做,因为你看它不会工作。
为了解释为什么 TextBlock
没有找到它的隐式样式,WPF中有一个奇怪的规则隐式样式只能通过inheritance自Control
类的元素跨模板边界inheritance; 不从Control
inheritance的元素不会探测父模板之外的隐式样式。
可以在FrameworkElement
找到负责此操作的代码:
// FindImplicitSytle(fe) : Default: unlinkedParent, deferReference internal static object FindImplicitStyleResource( FrameworkElement fe, object resourceKey, out object source) { ... // For non-controls the implicit StyleResource lookup must stop at // the templated parent. Look at task 25606 for further details. DependencyObject boundaryElement = null; if (!(fe is Control)) { boundaryElement = fe.TemplatedParent; } ... }
微软的Carole Snyder 解释了这种行为的原因 :
我被给出的原因是控件比元素更明显,并且控件的隐式样式可能应用于任何地方,其中不太可能普遍应用元素的隐式样式。 这个论点是合理的。 考虑以下:
Button通过最终创建TextBlock并将字符串添加到TextBlock来显示字符串。 如果Button中的TextBlock使用应用程序定义的隐式样式,则XAML将以这种方式呈现:
这可能不是你想要的行为。 另一方面,假设您正在创建一个很酷的UI,并且您希望所有的RepeatButton都具有特定的外观。 如果定义RepeatButton的外观一次,所有RepeatButtons都将使用该外观,即使RepeatButton在ControlTemplate中也是如此。