2012-07-01 2 views
1

Я хочу, чтобы линейка всегда была видимой, хотя я вижу полосу прокрутки. Ниже ИзображенияWPF Canvas Ruler Scrollbar issue

enter image description here

Если я прокручиваю вниз или прокрутки вправо, как холст правитель будет исчезли, когда я прокрутке всю панель в нижней/правой. И оба правителя - Dock.Left и Dock.To.

enter image description here

Как я могу установить как правитель всегда виден, даже если я прокручиваю весь путь прямо на дно. Я не могу установить панель прокрутки из боковой панели, потому что левая линейка должна двигаться вверх и вниз по вертикальной прокрутке, а горизонтальная линейка должна перемещаться влево и вправо в соответствии с горизонтальной прокруткой.

ответ

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> 

Edit:

Мои рассуждения для делая это пользовательский элемент управления является клюв ause я хотел gaurentee, чтобы ширина горизонтальной линейки и высота вертикальной линейки были такого же размера, как и видимое содержимое. Это было так, что я не получил странное поведение правителей, движущихся со слегка разными скоростями, по сравнению с содержанием из-за того, что область видимого содержимого немного меньше, чем полосы прокрутки, находящиеся внутри ScrollViewer.