【发布时间】:2017-03-22 11:08:44
【问题描述】:
我正在尝试调整 Infragistics DataRecordCellArea 的样式,以使 XamDataGrid 主要基于当前分配的样式(通过 ThemeManager,但可能在父元素上)。通常,如果主题的应用方式与系统主题相同,我会使用以下方式:
<!-- with xmlns:idp="http://infragistics.com/DataPresenter" -->
<Style
TargetType="{x:Type idp:DataRecordCellArea}"
BasedOn={StaticResource {x:Type idp:DataRecordCellArea}}
>
<!-- Style overrides -->
</Style>
将样式作为资源注入XamDataGrid,希望基于BasedOn 属性获取隐式样式。但是,这不是正在发生的事情:使用这种方法,我得到一个与 StaticResource 相关的 XamlParseException 无法找到资源 - 即没有样式可以作为基础。
“太棒了”,你可能会想,“只要去掉 based 就可以了。”这将是正确的,除非使用空样式这样做会明显影响控件的外观,因为它偏离了主题提供的内容。
我的预期解决方案是自定义 MarkupExtension,它采用命名 FrameworkElement 和目标类型,并尝试找到将要使用的隐式样式,如果我创建目标类型的实例作为上下文的子级 -提供对象。如果结果是默认样式(甚至是空值),那就这样吧。这对于开始使用样式时的密封也应该是安全的,因为我不需要响应上下文的变化,只需在构建样式时获取值即可。我想。
但是,当没有为实际样式属性找到显式值时,我无法解决的是如何检索元素的隐式样式。 Finding the default style 看起来很简单,但由于没有可提供给 Application.Current.FindResource() 方法的上下文,我相信这相当于将 BasedOn 属性留空。相反,如果我只是得到var implicit = Context.Resources.Contains(TargetType) ? Context.Resources[TargetType] : null;,我希望得到假空值,然后我希望只捕获ResourceDictionary 及其MergedDictionaries 集合的显式成员的样式。
还有可能更复杂:即我实际想要替换的样式可能不会仅使用类型键入。例如,假设主题可能将同一个对象用于多个目的,并且每个目的都有一个特定的键名,然后在为父对象配置 ControlTemplate 期间分配样式,即
<Style TargetType={XamDataGridOrSomeUnknownChildOfXamDataGrid}>
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ControlTemplate.Resources>
<Style TargetType="{TheTypeICareAbout}" x:Key="SomeActualKeyedValue" BasedOn="{StaticResource SomeThemeStyleOrKeyToTheDefaultOne}">
<!-- Style definition -->
</Style>
</ControlTemplate.Resources>
...
<TheTypeICareAbout Style="{StaticResource SomeActualKeyedValue}" />
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
目前,我希望这不是正在发生的事情,但至少有一些证据表明它可能是。如果有人知道在呈现ControlTemplate 时挂钩并覆盖该样式的方法,这也将回答我的问题-可能比找到隐式样式更好(因为那时我实际上并没有覆盖隐式样式)。
【问题讨论】:
-
在最后一种情况下(“进一步的复杂化”),我认为无论你做什么,风格都将永远是
SomeActualKeyedValue。 -
嗯 - 希望有一种方法可以说“给定这个对象,对于我的目标类型的任何创建实例,采用将应用于其自己设备的样式并构造一个新的,压倒一切,在其位置设置样式并应用它”。我猜样式的密封性质意味着您需要为每个实例创建一个新样式,或者至少对于每个已确定的候选样式都需要一个新样式来作为新样式的基础,但仍然如此。如果不可能,那就不可能。
-
嗯...考虑一下,我想知道我是否可以覆盖目标类型的
FrameworkPropertyMetaData以响应某些基本属性上的更改事件,然后在此处应用我的样式...可能有点矫枉过正,但我想这值得考虑...... -
您可以覆盖目标控件类型的
Style属性的元数据,然后在回调中执行var style = LoadYourStyle(); style.BasedOn = (Style) e.NewValue; targetControl.Style = style;。这将起作用,但前提是在该控件上显式设置样式。如果不是 - 将不会调用回调。另一方面,您可以将其与其他方法结合使用。
标签: c# wpf infragistics