即使滚动条可见,我也希望尺子始终可见。见下图
如果我向下滚动或向右滚动,当我将整个面板滚动到底部/右侧时,两个画布标尺都将消失。两个统治者都是 Dock.Left 和 Dock.To。
如何将两个标尺设置为始终可见,即使我一直滚动到底部。我不能将滚动条放在侧面板之外,因为左标尺需要根据垂直滚动上下移动,而水平标尺需要根据水平滚动左右移动。
我能想到的最好的方法是制作一个自定义控件来封装如下行为:
public class RulerScrollViewer : ScrollViewer
{
static RulerScrollViewer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RulerScrollViewer), new FrameworkPropertyMetadata(typeof(RulerScrollViewer)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.ScrollChanged -= RulerScrollViewer_ScrollChanged;
this.ScrollChanged += RulerScrollViewer_ScrollChanged;
}
void RulerScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
var h = this.Template.FindName("PART_HorizontalRulerScrollViewer", this) as ScrollViewer;
if (h != null)
h.ScrollToHorizontalOffset(this.HorizontalOffset);
var v = this.Template.FindName("PART_VerticalRulerScrollViewer", this) as ScrollViewer;
if (v != null)
v.ScrollToVerticalOffset(this.VerticalOffset);
}
}
public class HorizontalRuler : Control
{
protected override void OnRender(DrawingContext drawingContext)
{
for (int i = 0; i < this.ActualWidth / 100; i++)
{
var ft = new FormattedText(i.ToString(), CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("Tahoma"), 8, Brushes.Black);
drawingContext.DrawText(ft, new Point(i * 100, 0));
}
}
}
public class VerticallRuler : Control
{
protected override void OnRender(DrawingContext drawingContext)
{
for (int i = 0; i < this.ActualHeight / 100; i++)
{
var ft = new FormattedText(i.ToString(), CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("Tahoma"), 8, Brushes.Black);
drawingContext.DrawText(ft, new Point(0, i*100));
}
}
}
在 generic.xaml 中使用类似以下内容:
<ControlTemplate x:Key="RulerScrollViewer_Template" TargetType="local:RulerScrollViewer">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="PART_HorizontalRulerScrollViewer" Grid.Row="0" Grid.Column="1" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<local:HorizontalRuler Width="{Binding ElementName=content,Path=ExtentWidth}" Height="20" />
</ScrollViewer>
<ScrollViewer x:Name="PART_VerticalRulerScrollViewer" Grid.Row="1" Grid.Column="0" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<local:VerticallRuler Height="{Binding ElementName=content,Path=ExtentHeight}" Width="20" />
</ScrollViewer>
<ScrollContentPresenter Name="content" Grid.Row="1" Grid.Column="1" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Row="1" Grid.Column="2"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="2" Grid.Column="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type local:RulerScrollViewer}">
<Setter Property="Template" Value="{StaticResource RulerScrollViewer_Template}" />
</Style>
编辑:
我之所以将其设为自定义控件,是因为我想证明水平标尺的宽度和垂直标尺的高度与可见内容的大小相同。因此,由于可见内容区域比 ScrollViewer 内的滚动条略小,因此我没有得到标尺以与内容略有不同的速率移动的奇怪行为。