我的问题与此类似: Having an issue with my TextBox control template
但我想更进一步:
我的问题很简单: 我有模板控件(标签,文本框,复选框等......)。每个控件都有默认值,可以通过设置控件实例的属性值在运行时覆盖它们。无论为属性设置了什么值,我决定在IsEnabled = false时使用的值都应该占优势。
现在,我知道WPF中的值优先级阻止了这种行为的简单实现(正如我在另一个问题中所学到的那样:http://msdn.microsoft.com/en-us/library/ms743230.aspx)
但我设法找到了一个很好的工作方式,除了TextBox中的Foreground属性。 (只有这个具体情况)
所以,只需要处理前景值,这就是我在标签上做的事情:(为了更清晰,我摆脱了所有其他属性)
<Style TargetType="Label">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Border>
<ContentPresenter Name="ContentSite"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="ContentSite" Property="TextBlock.Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
所以基本上,默认情况下,Label会有一个蓝色文本,我可以通过在后面的代码中执行:myLabel.Foreground = Brushes.Green
覆盖,例如,绿色,然后,无论我设置什么,如果我写:MyLabel.IsEnabled = False
,文字将变为红色。
这项技术效果很好。 (即:xaml中的这一行将输出一个红色文本:<Label Foreground="Green" IsEnabled="False" />
)。它与所有其他控件的工作方式相同。
但是当尝试使用textBox重现它时,它根本不起作用。
这是我的代码:
<Style TargetType="TextBox">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Border Name="Border">
<ScrollViewer x:Name="PART_ContentHost" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_ContentHost" Property="Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我尝试在PART_ContentHost上添加Foreground="{TemplateBinding Foreground}"
但没有成功。
我怀疑这与PART_ContentHost是一个滚动查看器并且存在某种隐藏(至少来自我)继承的事实有关。
我能找到的唯一其他解释是TextBox类有一些特殊的处理方法,硬编码控件本身和它的PART_ContentHost部分之间的链接(绑定或propertychanged事件或其他什么?)
如果有人可以向我解释,这将是伟大的! 如果有人甚至可以提供一个很好的解决方案(一个不涉及讨厌的黑客,就像我现在使用的那个,但不会在这里显示,以免对读者造成严重的眼睛伤害),这将更大!
答案 0 :(得分:4)
默认情况下,ScrollViewer本身的模板看起来像这样:
<ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
<ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
<ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</ControlTemplate>
顺便说一句,我通过使用Blend从TextBox中获取了它。
我敢打赌,如果您将触发器添加到该模板中的ScrollContentPresenter
,那么您可以将其添加到标签中的ContentPresenter
,以便它适合您。