有没有发现TextBlockHighlightSource继承自FrameworkElement?这种奇特的写法是为了让TextBlockHighlightSource可以使用全局的Style。毕竟要在应用程序里统一Highlight的颜色还是全局样式最好使,但作为附加属性,TextBlockHighlightSource并不是VisualTree的一部分,它拿不到VisualTree上的Resources。最简单的解决方案是让TextBlockHighlightSource继承自FrameworkElement,把它放到VisualTree里,用法如下:
<StackPanel> <FrameworkElement.Resources> <Style TargetType="kino:TextBlockHighlightSource"> <Setter Property="LowlightForeground" Value="Blue"/> </Style> </FrameworkElement.Resources> <TextBox x:Name="FilterElement3"/> <kino:TextBlockHighlightSource Text="{Binding ElementName=FilterElement3,Path=Text}" HighlightForeground="DarkBlue" HighlightBackground="Yellow" x:Name="TextBlockHighlightSource2"/> <TextBlock Text="A very powerful projector with special features for Internet usability, USB" kino:TextBlockService.HighlightText="{Binding ElementName=TextBlockHighlightSource2}" TextWrapping="Wrap"/> </StackPanel>也许你会觉得这种写法有些奇怪,毕竟我也觉得在View上放一个隐藏的元素真的很怪。其实在一万二千年前微软就已经有这种写法,在的文档里就有用到:
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <riaControls:DomainDataSource x:Name="source" QueryName="GetProducts" AutoLoad="true"> <riaControls:DomainDataSource.DomainContext> <domain:ProductDomainContext /> </riaControls:DomainDataSource.DomainContext> <riaControls:DomainDataSource.FilterDescriptors> <riaData:FilterDescriptorCollection LogicalOperator="And"> <riaData:FilterDescriptor PropertyPath="Color" Operator="IsEqualTo" Value="Blue" /> <riaData:FilterDescriptor PropertyPath="ListPrice" Operator="IsLessThanOrEqualTo"> <riaControls:ControlParameter ControlName="MaxPrice" PropertyName="SelectedItem.Content" RefreshEventName="SelectionChanged" /> </riaData:FilterDescriptor> </riaData:FilterDescriptorCollection> </riaControls:DomainDataSource.FilterDescriptors> </riaControls:DomainDataSource> <ComboBox x:Name="MaxPrice" Grid.Row="0" SelectedIndex="0"> <ComboBoxItem Content="100" /> <ComboBoxItem Content="500" /> <ComboBoxItem Content="1000" /> </ComboBox> <data:DataGrid Grid.Row="1" ItemsSource="{Binding Data, ElementName=source}" /> </Grid>把DataSource放到View上这种做法可能是WinForm的祖传家训,结构可耻但有用。
4. 结语写这篇博客的时候我才发觉这个附加属性还叫HighlightText好像不太好,但也懒得改了。
这篇文章介绍了使用TypeConverter简化调用,以及继承自FrameworkElement以便使用Style。
5. 参考TypeConverter 类
TypeConverters 和 XAML
Type Converters for XAML Overview
TypeConverterAttribute Class
如何:实现类型转换器
TextBlock at master · DinoChan_Kino.Toolkit.Wpf