2013-07-02 30 views
0

我創建了一個代表圖形邊緣的自定義控件。在中間是重量顯示。在行的中間添加標籤

enter image description here(Circules是頂點和所述連接線是邊緣)

我通過繪製重量與重寫的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)); 




} 

我怎樣才能在該行的中間一個TextBlock /文本框顯示的重量?

+0

請勿在WPF中重寫'OnRender()'。這不是winforms。爲什麼不在ControlTemplate中添加所需的UI元素? –

+0

我不知道如何在行旁邊添加UI元素。另外UI元素應該放置在水平線的一半處。 – user885679

回答

0

我以前使用MultiBinding和轉換器做過類似的事情。

您綁定文本塊的頂部,作爲第一個點的Y和第二個點的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

+0

我不知道我是否正確理解你,因爲TextBlock不提供我可以綁定的Top Dp。此外,邊緣控制不包含畫布。 – user885679

+0

好吧,我認爲你需要閱讀http://msdn.microsoft.com/en-us/library/ms745058.aspx。我相信你的Edges應該在* Canvas裏面,這是唯一一個提供明確定位的容器。如果你仔細想想,你現在正在繪製重疊的邊線(全部從0,0開始),這些邊線只發生在其右下角的畫線,或者(可能是因爲你已經覆蓋了OnRender)在其控制範圍之外。我很確定這會在以後引起你的問題。 – AlSki