【问题标题】:How can I get a tooltip over the whole of a WPFToolkit LineSeries?如何获得整个 WPFToolkit LineSeries 的工具提示?
【发布时间】:2013-06-14 20:54:36
【问题描述】:

我正在绘制一个 WPFToolkit LineSeries 图,除了工具提示之外,它都可以正常工作。我想要一个工具提示来显示鼠标线上 any 点的 x 和 y 值。我发现这适用于 DataPoints(在我的情况下相当稀疏):http://istacee.wordpress.com/2013/03/19/wpf-toolkit-chart-custom-tooltip-on-lineseries-charts/,这适用于图表区域上的任何点:Show series value over any point on chart using tooltip c#

这是我目前的代码:

<Grid.Resources>
  <ResourceDictionary>
      <ControlTemplate x:Key="CommonLineSeriesDataPointTemplate" TargetType="chartingToolkit:LineDataPoint">
        <Grid x:Name="Root" Opacity="1" />
      </ControlTemplate>

      <Style x:Key="CommonLineSeriesDataPoint" TargetType="chartingToolkit:LineDataPoint">
        <Setter Property="Template" Value="{StaticResource CommonLineSeriesDataPointTemplate}" />
      </Style>

      <Style x:Key="lineSeriesStyle" TargetType="{x:Type chartingToolkit:LineSeries}">
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="DataPointStyle" Value="{StaticResource CommonLineSeriesDataPoint}" />
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="chartingToolkit:LineSeries">
              <Canvas x:Name="PlotArea">
                <Polyline Points="{TemplateBinding Points}" >
                  <Polyline.Stroke>
                    <SolidColorBrush Color="Red"/>
                  </Polyline.Stroke>
                </Polyline>
              </Canvas>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>

      <DataTemplate x:Key="chartTemplate" DataType="{x:Type Views:GraphCurve}">
        <chartingToolkit:LineSeries ItemsSource="{Binding}" 
                                  IndependentValuePath="X" 
                                  DependentValuePath="Y" 
                                  Style="{StaticResource lineSeriesStyle}" />
      </DataTemplate>
  </ResourceDictionary>
</Grid.Resources>

<chartingToolkit:Chart BorderBrush="DarkGray" 
                         SeriesSource="{Binding GraphItems}"
                         SeriesTemplate="{StaticResource chartTemplate}">

  <chartingToolkit:Chart.Axes>
    <chartingToolkit:LinearAxis Orientation="X" />
    <chartingToolkit:LinearAxis Orientation="Y" />
  </chartingToolkit:Chart.Axes>
</chartingToolkit:Chart>

有什么想法吗?

【问题讨论】:

    标签: wpftoolkit


    【解决方案1】:

    您可以尝试使用MouseMove 事件,并跟踪鼠标的位置以显示在折线的工具提示中。 IRangeAxis 提供了一个方法GetValueAtPosition,它获取一个像素坐标并将其转换为轴坐标中的值。

    首先,将工具提示添加到您的折线:

    <Polyline Points="{TemplateBinding Points}" >
        <Polyline.Stroke>
            <SolidColorBrush Color="Red"/>                                      
        </Polyline.Stroke>
        <Polyline.ToolTip>
            <ToolTip>
                <StackPanel>
                    <TextBlock Text="{Binding HoverPoint.X}"/>
                    <TextBlock Text="{Binding HoverPoint.Y}"/>
                </StackPanel>
            </ToolTip>
        </Polyline.ToolTip>
    </Polyline>
    

    这里我绑定了这个视图的视图模型的一个属性,叫做HoverPoint。确保在您的视图模型中定义它(我使用的是 ReactiveUI,但您可以使用其他实现 INotifyPropertyChanged 的东西):

    private Point hoverPoint;
    public Point HoverPoint
    {
        get { return hoverPoint; }
        set { this.RaiseAndSetIfChanged(me => me.HoverPoint, ref hoverPoint, value); }
    }
    

    最后,当鼠标在图表区域移动时,我们需要更新这个属性。然后绑定将负责更新工具提示。如果您在图表上为 MouseMove 事件添加处理程序:

    <chartingToolkit:Chart MouseMove="Chart_MouseMove" ...
    

    然后像这样填写处理程序:

        private void Chart_MouseMove(object sender, MouseEventArgs e)
        {
            var chart = (Chart)sender;
            var xAxisRange = (IRangeAxis)xAxis;
            var yAxisRange = (IRangeAxis)yAxis;
    
            var plotArea = FindDescendantWithName(chart, "PlotArea");
            if (plotArea == null)
            {
                return;
            }
            var mousePositionInPixels = e.GetPosition(plotArea);
            var mouseXPositionInChartUnits = (double)xAxisRange.GetValueAtPosition(new UnitValue(mousePositionInPixels.X, Unit.Pixels));
            var mouseYPositionInChartUnits = (double)yAxisRange.GetValueAtPosition(new UnitValue(plotArea.Height - mousePositionInPixels.Y, Unit.Pixels));
    
            ((MainWindowViewModel)DataContext).HoverPoint = new Point(mouseXPositionInChartUnits, mouseYPositionInChartUnits);
        }
    
        public static FrameworkElement FindDescendantWithName(DependencyObject root, string name)
        {
            var numChildren = VisualTreeHelper.GetChildrenCount(root);
    
            for (var i = 0; i < numChildren; i++)
            {
                var child = (FrameworkElement) VisualTreeHelper.GetChild(root, i);
                if (child.Name == name)
                {
                    return child;
                }
    
                var descendantOfChild = FindDescendantWithName(child, name);
                if (descendantOfChild != null)
                {
                    return descendantOfChild;
                }
            }
    
            return null;
        }
    

    首先,我们获取图表和轴的引用(我在 XAML 中将轴命名为 xAxisyAxis)。

    然后,我们需要找到图表模板的PlotArea 部分,即绘制图表的位(不包括轴等)。可能有更好的方法来解决这个问题,但我使用了一个简单的调用 FindDescendantWithName 的方法来访问它。

    然后,我使用GetPosition 来获取鼠标相对于该图表绘图区域的位置。最后,坐标轴上的GetValueAtPosition 方法为我们提供了当前鼠标位置的图表坐标值,我们在HoverPoint 属性中设置这些坐标。

    唯一的问题是图形线的粗细是有限的,因此您实际上可以四处移动鼠标并看到相同的 X 值的不同 Y 值,反之亦然。但是,扩展它以找到最近的绘图点并不难。然后,您可以将工具提示捕捉到最近的点。或者,如果您找到两个最近的点(一个在鼠标的左侧,一个在鼠标的右侧),您可以自己进行插值并计算出 Y 对应于 X 的当前值。我想这取决于你有多少如果值得这样做,请关心线条的粗细。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多