我创建了派生TextBox的HighlightTextBox。代码如下所示。
<Style TargetType="{x:Type host:HighlightTextBox}">
<Setter Property="AcceptsReturn" Value="True" />
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="Foreground" Value="#00000000"/>
<Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FontSize, Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="textArea" TargetType="{x:Type host:HighlightTextBox}">
<Border BorderThickness="{Binding BorderTickness}"
BorderBrush="{Binding BorderBrush}"
Background="{Binding BackGround}">
<Grid Margin="{TemplateBinding Padding}" x:Name="PART_Grid">
<host:TextCanvas x:Name="PART_RenderCanvas" ClipToBounds="True"
TextOptions.TextRenderingMode="ClearType" TextOptions.TextFormattingMode="Display"
LineHeight="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=LineHeight}"/>
<ScrollViewer x:Name="PART_ContentHost" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
重点是ControlTemplate。如您所见,HighlightTextBox的内容由TextCanvas和ScrollViewer组成。
HighlightTextBox通过在TextCanvas上绘画来突出显示当前选定的行,但它会如下所示侵入VerticalScrollViewer部分。
我想通过不入侵VerticalScrollViewer来显示它。
我认为原因可能是TextCanvas占据了TextBox的整个部分。因此,我尝试将TextCanvas移到ScrollViewer中,但是这种方式使运行时出现错误,即“ PART_ContentHost不能具有子元素。
我认为另一种方法是获取TextBox的内容宽度,而不是VerticalScrollBar的宽度,并将其绑定到TextCanvas的宽度。但我不知道该如何获得。
我应该怎么解决这个问题?如果您有更好的方法或其他解决方法,请告诉我。
谢谢您的阅读。
Search the visual tree用于您的ScrollViewer的内容演示者,这将为您提供内容区域本身的宽度:
var scrollViewer = yourTextBox.Template.FindName("PART_ContentHost", yourTextBox) as ScrollViewer;
var contentPresenter = UIHelper.FindChild<ScrollContentPresenter>(scrollViewer, String.Empty);
var width = contentPresenter.ActualWidth;
更新:您可以像这样直接绑定到ScrollContentPresenter的内容控件:
<Grid Margin="{TemplateBinding Padding}" x:Name="PART_Grid">
<TextBlock Text="{Binding ElementName=PART_ContentHost, Path=Content.ActualWidth}" Background="CornflowerBlue" VerticalAlignment="Top"/>
<ScrollViewer x:Name="PART_ContentHost" />
</Grid>
请记住,尽管这为您提供了ScrollViewers的宽度content宽度,在上面的示例中,由于ScrollViewers的内容是一个具有2,0,2,0边距的TextBoxView:
为了补偿这一点,您可能需要将Canvas边距绑定到TextBoxView边距(在我的情况下是TextBlock而不是Canvas):
<Grid Margin="{TemplateBinding Padding}" x:Name="PART_Grid">
<TextBlock Text="{Binding ElementName=PART_ContentHost, Path=Content.ActualWidth}"
Margin="{Binding ElementName=PART_ContentHost, Path=Content.Margin}"
Background="CornflowerBlue" VerticalAlignment="Top" />
<ScrollViewer x:Name="PART_ContentHost" Padding="0" Margin="0"/>
</Grid>
这将使您的画布在父网格中的对齐方式与TextBoxView的对齐方式相同,以便所有内容正确对齐:
((您也可以只删除TextBoxView的边距,但这可能不是您想要的。)>