C# 在中间添加标签

C# 在中间添加标签,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我创建了一个表示图形边缘的自定义控件。在中间的重量显示。 (圆圈是顶点,连接线是边) 我通过使用覆盖的OnRender方法绘制权重来实现这一点。但这不是一个好的解决方案 无法通过文本框等方式使权重可编辑。因此,如果我可以将TextBox或ContentPresenter添加到重写的OnRender方法中,以使权重可编辑,那就太好了。但是我不知道怎么做 无论如何,这是我目前的状态: <Style TargetType="{x:Type local:Edge}"> <S

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

(圆圈是顶点,连接线是边)

我通过使用覆盖的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>

控件的代码隐藏:

 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));




}
公共类边缘:控件
{
静态边()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Edge),new FrameworkPropertyMetadata(typeof(Edge));
}
受保护的重写void OnRender(DrawingContext DrawingContext)
{
base.OnRender(drawingContext);
点p=新点((位置V.X+位置U.X)/2+4,(位置V.Y+位置U.Y)/2);
drawingContext.DrawText(新格式化文本(权重!=null?权重.ToString():“”,
System.Globalization.CultureInfo.CurrentCulture,FlowDirection.LeftToRight,新字体(this.FontFamily.ToString()),
这个。字体大小,这个。前景),p);
}
公共整数权重
{
获取{return(int)GetValue(WeightProperty);}
set{SetValue(WeightProperty,value);}
}
//使用DependencyProperty作为权重的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读DependencyProperty WeightProperty=
DependencyProperty.Register(“权重”、typeof(int)、typeof(Edge)、新UIPropertyMetadata(0));
/// 
///从对应的U顶点控件获取或设置位置的值
/// 
公共点位置
{
获取{return(Point)GetValue(positionuperty);}
set{SetValue(positionuperty,value);}
}
//使用DependencyProperty作为PositionU的后台存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性PositionProperty属性=
DependencyProperty.Register(“位置U”、类型(点)、类型(边缘)、新UIPropertyMetadata(新点());
/// 
///从对应的V顶点控件获取或设置位置的值
/// 
公共点位置
{
获取{return(Point)GetValue(PositionVProperty);}
set{SetValue(PositionVProperty,value);}
}
//使用DependencyProperty作为PositionV的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性PositionProperty=
DependencyProperty.Register(“PositionV”、typeof(Point)、typeof(Edge)、新UIPropertyMetadata(null));
}

我如何在文本的中间显示文本块/文本框的重量?

< p>我以前使用过多绑定和转换器做了类似的事情。

将textblock的顶部作为多重绑定绑定到第一个点的Y和第二个点的Y,并使用转换器将它们平均为单个值,然后对Left=X的平均值重复此操作

差不多

<Canvas.Left>
  <MultiBinding Converter="{StaticResource findCentreConverter}">
     <Binding ElementName=yourLine, Path=X1/>
     <Binding ElementName=yourLine, Path=X2/>
  </MultiBinding>
</Canvas.Left>
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的偏移量,以避免出现这种情况。请看一个带有参数的示例。

不要在WPF中重写
OnRender()
。这不是winforms。为什么不在ControlTemplate中添加所需的UI元素呢?我不知道如何在行旁边添加UI元素。此外,UI元素应该水平放置在行的一半。我不知道我是否理解正确,因为TextBlock没有提供我可以绑定的顶部Dp。另外,边缘控件不包含画布。好的,我认为您需要阅读。我相信你的边缘应该在画布中,画布是唯一提供明确定位的容器。如果仔细想想,您当前正在绘制重叠边(所有边都从0,0开始),这些边恰好只绘制向下推到其右下角的线,或者(可能是因为您已覆盖OnRender)在其控制边界之外的线。我很确定这会给你带来麻烦。