-2

我有一个类型的集合MyType { double X, double Y, string Text }

如何将其显示为带有 X、Y 坐标的点(或标记)以及带有 Text 作为文本的标签?

  • 标签必须经常看到 - 所以没有工具提示。
  • Text 属性因点而异。
4

1 回答 1

1

好吧,解决方案是使用文本依赖属性制作自己的标记,然后将映射添加到该属性。它涉及到这样的事情(它看起来有点肮脏,但它说明了主要思想)。它是带有标签的脉冲序列,每个脉冲开始时都有持续时间:

没有次要属性的自定义标记类(我不是从 ShapeElementPointMarker 派生的,因为最后一个对我来说有不受欢迎的属性):

public class LabeledPointMarker : ElementPointMarker
{
    #region TextProperty
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(LabeledPointMarker));

    public string Text
    {
        get { return (string)this.GetValue(LabeledPointMarker.TextProperty); }
        set { this.SetValue(LabeledPointMarker.TextProperty, value); }
    }
    #endregion TextProperty

    // ...
    // Another dependency properties in the same manner.
    // ...

    public override UIElement CreateMarker()
    {
        TextBlock tb = new TextBlock()
        {
            Text = this.Text,
            Foreground = this.TextBrush
        };

        Border b = new Border()
        {
            BorderBrush = this.BorderBrush,
            BorderThickness = this.BorderThickness,
            Background = this.BorderBackground,
            Child = tb
        };

        return b;
    }

    public override void SetPosition(UIElement marker, Point screenPoint)
    {
        Canvas.SetLeft(marker, screenPoint.X - marker.DesiredSize.Width / 2);
        Canvas.SetTop(marker, screenPoint.Y - marker.DesiredSize.Height / 2);
    }
}

现在您可以创建一个“N 维集合”(简单来说),它是一个复杂类型的一维集合。对我来说,我只使用元组:

var data =
    results.Data
    .Select(d => 
        new Tuple<double, double, string>(
        d.StartIndex, 
        0, 
        d.DurationTime.ToString("######.####")))
    .ToList();

然后创建数据源,设置映射(另一个键 - AddMapping 方法),创建标记模板(并在模板中设置未在映射中设置的属性),创建 ElementMarkerPointsGraph,将地图源和标记模板添加到此图,最后将此图添加到绘图仪(对不起我的英语 - 我不是英语使用者:)):

EnumerableDataSource<Tuple<double, double, string>> dataSource =
    new EnumerableDataSource<Tuple<double, double, string>>(data);
dataSource.SetXMapping(x => x.Item1);
dataSource.SetYMapping(y => y.Item2);
dataSource.AddMapping(LabeledPointMarker.TextProperty, t => t.Item3);

ElementMarkerPointsGraph empg = new ElementMarkerPointsGraph();
empg.DataSource = dataSource;
empg.Marker = new LabeledPointMarker()
{
    TextBrush = Brushes.Black,
    BorderBackground = Brushes.Red,
    BorderBrush = Brushes.Purple,
    BorderThickness = new Thickness(2)
};

chartPlotter.Children.Add(empg);

此外,它可能需要返回的不是 CreateMarker 中相同的 UIElement,而是它的副本。否则它可能会因为映射到同一个 UIElement(上面代码的“dataSource.AddMapping”部分)而引发异常。由于 UIElement 是一个对象,因此获取其副本可能并非易事。所以我发现最简单的方法是使用这样的复制技术

于 2013-10-24T10:26:09.693 回答