1

スクロールバーが表示されていても、ルーラーを常に表示したい。以下の画像を参照してください

ここに画像の説明を入力

下または右にスクロールすると、パネル全体を下/右にスクロールしているため、両方のキャンバス ルーラーが消えます。そして両方のルーラーは Dock.Left と Dock.To です。

ここに画像の説明を入力

一番下までスクロールしても、両方のルーラーを常に表示するように設定するにはどうすればよいですか。左ルーラーは垂直スクロールで上下に移動し、水平ルーラーは水平スクロールで左右に移動する必要があるため、サイド パネルの外にスクロール バーを配置できません。

4

1 に答える 1

1

これを実行するために考えられる最も良い方法は、次のような動作をカプセル化するカスタム コントロールを作成することです。

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 内にあるスクロールバーから表示されるコンテンツ領域がわずかに小さいため、ルーラーがコンテンツに対してわずかに異なる速度で移動するという奇妙な動作を取得しなかったためです。

于 2012-07-02T05:07:17.120 に答える