为什么某些属性需要在 DataTrigger 生效之前在样式中定义默认值?
为什么有些依赖属性需要在样式中有一个默认的setter,触发的setter才会生效?
例如,
<ContentControl>
<ContentControl.Resources>
<DataTemplate x:Key="DefaultTemplate">
<TextBlock Text="Default Template" />
</DataTemplate>
<DataTemplate x:Key="MouseOverTemplate">
<TextBlock Text="MouseOver Template" />
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<!-- Triggered setter will work without this default setter -->
<!--<Setter Property="ContentTemplate"
Value="{StaticResource DefaultTemplate}" />-->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate"
Value="{StaticResource MouseOverTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
我在某处看到过很好的解释,但我不记得在哪里。我记得它与WPF应用依赖属性值的顺序,但我不记得细节,或者为什么有些属性需要在触发器生效之前定义默认值,而其他属性则不需要。
Why is it that some dependency properties need to have a default setter in the style before the triggered setters will take effect?
For example,
<ContentControl>
<ContentControl.Resources>
<DataTemplate x:Key="DefaultTemplate">
<TextBlock Text="Default Template" />
</DataTemplate>
<DataTemplate x:Key="MouseOverTemplate">
<TextBlock Text="MouseOver Template" />
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<!-- Triggered setter will work without this default setter -->
<!--<Setter Property="ContentTemplate"
Value="{StaticResource DefaultTemplate}" />-->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate"
Value="{StaticResource MouseOverTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
I saw a good explanation of it somewhere, but I can't remember where. I recall it had something to do with the order that WPF applies dependency property values, but I can't remember the details, or why some properties need the default defined before triggers will take effect, while others do not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的第一个
Style
不起作用,我会感到非常惊讶,除非您的ContentControl
定义如下:如果是这样,那么它将与值优先级有关。从您的链接中,像我的示例中那样的设置将位于#3。因此,唯一可以覆盖它的是动画或者该值是否被强制。
Style
或ControlTemplate
(如果有)都无法更改ContentControl.ContentTemplate
属性。使用第二个
Style
,您可以像这样定义ContentControl
:在本例中,
DefaultTemplate
的Setter
是在 #8 处,因此触发器可以覆盖它(就像在 #6 处一样)。再次假设您:
那么可以覆盖
ControlTemplate
中使用的DataTemplate
,但无法更改ContentControl.ContentTemplate
' s 值。类似于:在这里,我们切换 ContentPresenter 使用的
DataTemplate
,以便它有效地忽略ContentControl.ContentTemplate
属性。但根据您的更新,鼠标没有“悬停”的情况。 ContentControl 尚未渲染任何内容(甚至没有透明像素),因此它不会接收任何鼠标事件。您可以执行以下操作来纠正它:
并且您需要在 ContentControl 上设置 Background="Transparent"。
I would be very surprised if your first
Style
does not work, unless yourContentControl
is defined like:If so, then it would have to do with value precedence. From your link, setting like in my example would be at #3. So the only thing that could override it would be an animation or if the value were coerced. Neither the
Style
or theControlTemplate
(if any) could change theContentControl.ContentTemplate
property.With your second
Style
, you could define yourContentControl
like so:In this case, the
Setter
forDefaultTemplate
is at #8 so the triggers can override it (as they are at #6).Assuming again, that you have:
Then it is possible to override the
DataTemplate
used in theControlTemplate
, but you cannot change theContentControl.ContentTemplate
's value. Something like:Here, we switch the
DataTemplate
used by the ContentPresenter so it effectively ignores theContentControl.ContentTemplate
property.Based on your updates though, there is nothing for the mouse to be "over". The ContentControl has not rendered anything (not even a transparent pixel), so it would not receive any mouse events. You can do something like this to correct it:
And you'd need to set Background="Transparent" on the ContentControl.