2013-07-02 2 views
0

그래프의 가장자리를 나타내는 사용자 정의 컨트롤을 만들었습니다. 가운데에 체중이 표시됩니다.라인 중간에 레이블 추가

enter image description here은 (Circules 정점이며 연결 라인 에지 임)

내가의 OnRender 메소드를 재정의 중량 드로잉하여 만들었다. 그러나 이것은 좋은 해결책이 아닙니다.

예를 들어 텍스트 상자로 가중치를 편집 할 수있는 방법이 없습니다. 따라서 가중치를 편집 가능하게 만들기 위해 재정의 된 OnRender 메서드에 TextBox 또는 ContentPresenter를 추가 할 수 있다면 좋을 것입니다. 그러나 나는 이것을 어떻게하는지 모른다.

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/텍스트 상자에 무게를 표시 할 수 있습니다 컨트롤

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

코드 숨김 :

어쨌든,이 내 현재 상태입니까?

+0

WPF에서'OnRender()'를 재정의하지 마십시오. 이것은 winforms가 아닙니다. 왜 ControlTemplate에 원하는 UI 요소를 추가하지 않습니까? –

+0

줄 옆에 UI 요소를 추가하는 방법을 모르겠습니다. 또한 UI 요소는 선의 절반에 수평으로 배치해야합니다. – user885679

답변

0

이전에 MultiBinding 및 변환기를 사용하여 비슷한 작업을했습니다.

첫 번째 점의 Y와 두 번째 점의 Y에 멀티 바인드로 바인더를 사용하고 변환기를 사용하여 단일 값으로 평균 한 다음 Left = X의 평균에 대해 반복합니다 . Canvas.Top

하고 FindCentreConverter에 대한

뭔가

같은
<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 오프셋을 피하기 위해 추가 값이나 매개 변수를 취하도록 변환기를 수정할 수 있습니다. 매개 변수가있는 예를 보려면 http://msdn.microsoft.com/en-us/library/system.windows.data.multibinding.aspx을보십시오.

+0

TextBlock이 바인딩 할 수있는 상위 Dp를 ​​제공하지 않기 때문에 올바르게 이해할 수 있는지 잘 모르겠습니다. 또한 Edge Control에는 캔버스가 없습니다. – user885679

+0

좋습니다. http://msdn.microsoft.com/en-us/library/ms745058.aspx를 읽어야합니다. 나는 당신의 엣지가 명백한 위치 지정을 제공하는 유일한 컨테이너 인 Canvas 내부에 있어야한다고 생각합니다. 이것에 대해 생각해 보면 현재 오버 헤드가있는 가장자리 (0,0부터 시작)를 그리는 중입니다. 맨 아래 오른쪽 모서리로 밀린 선만 또는 (OnRender를 재정의했기 때문에) 제어 경계 외부로 선을 그립니다. 나는 이것이 당신에게 나중에 문제를 일으킬 것이라고 확신합니다. – AlSki