在行的中间添加标签

时间:2013-07-02 13:53:42

标签: c# .net wpf xaml

我创建了一个代表图表边缘的自定义控件。在中间是显示的重量。

enter image description here(循环是顶点,连接线是边缘)

我是通过使用重写的OnRender方法绘制权重来实现的。但这不是一个好的解决方案。

无法通过文本框使重量可编辑。因此,如果我可以将一个TextBox或ContentPresenter添加到重写OnRender方法以使权重可编辑,那将会很棒。但我不知道该怎么做。

无论如何,这是我现在的状态:

  <Style TargetType="{x:Type local:Edge}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:Edge}">
                <DockPanel>
                    <Line Stroke="{TemplateBinding Foreground}" 
                    X1="{Binding Mode=TwoWay,Path=PositionU.X,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:Edge}}}"
                    Y1="{Binding Mode=TwoWay,Path=PositionU.Y,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:Edge}}}"
                    X2="{Binding Mode=TwoWay,Path=PositionV.X,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:Edge}}}"
                    Y2="{Binding Mode=TwoWay,Path=PositionV.Y,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:Edge}}}" >
                    </Line>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

控件的CODEBehind:

 public class Edge : Control
{
    static Edge()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Edge), new FrameworkPropertyMetadata(typeof(Edge)));

    }
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        Point p = new Point((PositionV.X + PositionU.X) / 2 + 4, (PositionV.Y + PositionU.Y) / 2);

        drawingContext.DrawText(new FormattedText(Weight != null ? Weight.ToString() : "",
            System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(this.FontFamily.ToString()),
            this.FontSize, this.Foreground), p);

    }

    public int Weight
    {
        get { return (int)GetValue(WeightProperty); }
        set { SetValue(WeightProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Weight.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WeightProperty =
        DependencyProperty.Register("Weight", typeof(int), typeof(Edge), new UIPropertyMetadata(0));


    /// <summary>
    /// Gets or sets the value of the position from the correspondending U Vertex control
    /// </summary>
    public Point PositionU
    {
        get { return (Point)GetValue(PositionUProperty); }
        set { SetValue(PositionUProperty, value); }
    }

    // Using a DependencyProperty as the backing store for PositionU.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PositionUProperty =
        DependencyProperty.Register("PositionU", typeof(Point), typeof(Edge), new UIPropertyMetadata(new Point()));



    /// <summary>
    /// Gets or sets the value of the position from the correspondending V Vertex control
    /// </summary>
    public Point PositionV
    {
        get { return (Point)GetValue(PositionVProperty); }
        set { SetValue(PositionVProperty, value); }
    }

    // Using a DependencyProperty as the backing store for PositionV.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PositionVProperty =
        DependencyProperty.Register("PositionV", typeof(Point), typeof(Edge), new UIPropertyMetadata(null));




}

如何在行中间使用TextBlock / TextBox显示权重?

1 个答案:

答案 0 :(得分:0)

我以前通过使用MultiBinding和转换器完成了类似的工作。

绑定文本块的顶部,作为第一个点的Y和第二个点的Y的多重绑定,并使用转换器将它们平均为单个值,然后重复左边= X的平均值&# 39; S

这样的东西
<Canvas.Left>
  <MultiBinding Converter="{StaticResource findCentreConverter}">
     <Binding ElementName=yourLine, Path=X1/>
     <Binding ElementName=yourLine, Path=X2/>
  </MultiBinding>
</Canvas.Left>

重复Canvas.Top

并且您的FindCentreConverter类似于

public class FindCentreMultiConverter : IMultiValueConverter
{
  public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    var point1 = (double)values[0];
    var point2 = (double)values[1];
    return (double)((point1 + point2) / 2.0d);
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

显然,这会将文本从行的中心开始,但您可以修改转换器以获取其他值或参数,例如X / Y的偏移量以避免这种情况。有关参数的示例,请查看http://msdn.microsoft.com/en-us/library/system.windows.data.multibinding.aspx