0

グラフの端を表すカスタム コントロールを作成しました。真ん中に体重が表示されます。

ここに画像の説明を入力(円が頂点、接続線が辺)

これは、オーバーライドされた OnRender メソッドでウェイトを描画することで作成しました。しかし、これは良い解決策ではありません。

たとえばテキストボックスで重みを編集可能にする方法はありません。そのため、オーバーライドされた OnRender メソッドに TextBox または ContentPresenter を追加して、重みを編集可能にできれば素晴らしいと思います。しかし、これを行う方法がわかりません。

とにかく、これは私の現在の状態です:

  <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 を使用して重みを表示するにはどうすればよいですか?

4

1 に答える 1

0

MultiBinding とコンバーターを使用して、以前に同様のことを行いました。

最初のポイントの Y と 2 番目のポイントの Y へのマルチバインディングとして、テキストブロックの上部をバインドし、コンバーターを使用してそれらを単一の値に平均化し、左 = X の平均を繰り返します。

何かのようなもの

<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をご覧ください。

于 2013-07-03T09:16:37.357 に答える