如何制作带注释的滚动条?

时间:2017-02-10 10:59:26

标签: c# wpf windows xaml

我正在使用DataGrid来显示一些信息。

我想为此ScrollBar添加带注释的DataGrid(以突出显示行,就像在VS中一样)

我的App.xaml中有ControlTemplate。我在“AnnotationCanvas”中添加了一个矩形作为示例,但我们的想法是自动填充此画布。

但是,我无法获得对此画布的引用。

我尝试了dataGrid.FindName("AnnotationCanvas")dataGrid.FindResource("AnnotationCanvas"),但没有成功。

我怎么能这样做?提前谢谢。

<ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">
  <Grid x:Name="grid">
    <Grid.RowDefinitions>
      <RowDefinition MaxHeight="18" />
      <RowDefinition Height="0.00001*" />
      <RowDefinition MaxHeight="18" />
    </Grid.RowDefinitions>
    <Border Grid.RowSpan="3"
            CornerRadius="2"
            Background="#F0F0F0" />

    <Canvas x:Name="AnnotationCanvas"
            Grid.Row="1">
      <!--ANNOTATIONS GO HERE-->
      <Rectangle Width="3"
                 Height="30"
                 Fill="Red" />
    </Canvas>

    <RepeatButton Grid.Row="0"
                  Style="{StaticResource ScrollBarLineButton}"
                  Height="18"
                  Command="ScrollBar.LineUpCommand"
                  Content="M 0 4 L 8 4 L 4 0 Z" />
    <Track Name="PART_Track"
           Grid.Row="1"
           IsDirectionReversed="true">
      <Track.DecreaseRepeatButton>
        <RepeatButton Style="{StaticResource ScrollBarPageButton}"
                      Command="ScrollBar.PageUpCommand" />
      </Track.DecreaseRepeatButton>
      <Track.Thumb>
        <Thumb Style="{StaticResource ScrollBarThumb}"
               Margin="1,0,1,0"
               Background="{StaticResource HorizontalNormalBrush}"
               BorderBrush="{StaticResource HorizontalNormalBorderBrush}" />
      </Track.Thumb>
      <Track.IncreaseRepeatButton>
        <RepeatButton Style="{StaticResource ScrollBarPageButton}" 
                      Command="ScrollBar.PageDownCommand" />
      </Track.IncreaseRepeatButton>
    </Track>
    <RepeatButton Grid.Row="3"
                  Style="{StaticResource ScrollBarLineButton}"
                  Height="18"
                  Command="ScrollBar.LineDownCommand"
                  Content="M 0 0 L 4 4 L 8 0 Z" />
  </Grid>
</ControlTemplate>

1 个答案:

答案 0 :(得分:1)

我发现我用来从DataGrid到ScrollBar的VisualTreeHelper无法正常工作,Control没有完全加载。 InitializeComponent()还不够,我不得不等待Loaded事件触发。

这是我的代码(工作):

private Canvas annotationCanvas;
private void Loaded(object sender, RoutedEventArgs e) {

    ScrollBar scrollBar = GetVisualChild<ScrollBar>(table);
    annotationCanvas = (Canvas)scrollBar.Template.FindName("AnnotationCanvas", scrollBar);

    UpdateAnnotations();
}

private static T GetVisualChild<T>(DependencyObject parent) where T : Visual {
    T child = default(T);

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++) {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null) {
            child = GetVisualChild<T>(v);
        }
        if (child != null) {
            break;
        }
    }
    return child;
}

// Fill the Canvas with horizontal markers. Can be optimized.
private void UpdateAnnotations() {
    if (annotationCanvas == null)
        return;

    annotationCanvas.Children.Clear();

    int i = 0;
    double m = items.Count;
    double height = table.ActualHeight;

    foreach (Item item in items) {
        if (item.someCondition) {
            int p = (int)(height * i / m);
            annotationCanvas.Children.Add(new Line() { X1 = 0, Y1 = p, X2 = 30, Y2 = p, StrokeThickness = 1, Stroke = Brushes.Red });
        }
        i++;
    }
}