我正在尝试为DataRecordCellArea
调整一个Infragistics 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
属性选择隐式样式。但是,这不是正在发生的事情:使用这种方法,我得到XamlParseException
与StaticResource
相关的无法找到资源 - 即没有基于事物的风格
&#34;伟大&#34;,你可能会想,&#34;只是摆脱基于它的工作。&#34;这是正确的,除非这样做是空的样式显然会影响控件的外观,因为它偏离了主题提供的内容。
我想要的解决方案是一个自定义MarkupExtension,它采用一个名为FrameworkElement
和一个目标类型,并试图找到正在使用的隐式样式,我将创建一个目标类型的实例作为上下文提供对象。如果结果是默认样式(甚至是空值),那么就这样吧。在开始使用样式时,这应该是安全的,因为我不需要响应上下文中的更改,只需在构造样式时获取值。我想。
然而,我无法解决的问题是,如果没有找到实际样式属性的显式值,那么如何检索元素的IMPLICIT样式。 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
时挂钩并覆盖THAT样式的方法,这也会回答我的问题 - 可能比找到隐式样式更好(因为那时我并没有真正覆盖隐含的样式)。
答案 0 :(得分:0)
我最终采用的方法(忽略现在的复杂情况)是编写一个标记扩展,它为上下文和目标类型提供了FrameworkElement。从那里可以看出,所有FrameworkElements都有一个FindResource()
方法(不仅仅是Application),因此只需调用FindResource
就可以了,因为它与上下文对象有关。
结果是xaml看起来像:
<Style
TargetType={x:Type TheTypeIWant}
BasedOn={BasedOnWithContext Context={x:ref NameOfContextProvidingObject},TargetType={x:Type TheTypeIWant}}
/>
...和C#看起来像:
public class BasedOnWithContextExtension : MarkupExtension
{
public BasedOnWIthContextExtension()
{
}
public DependencyObject Context {get; set;}
public Type TargetType {get; set;}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this.Context?.FindResource(this.TargetType) as Style;
}
}
(注意以上是我的解决方案的近似值,因为我没有代码库,并且暂时没有尝试编译它,但它应该提供一个关于有效方法的公平想法。)
这将很好地评估创建样式的时间点,找到隐式样式,并将其基于该样式。它找不到具有未知(或已知)键的样式并替换它们(根据复杂的情况)。