2016-08-14 31 views
0

と非常によく似た行番号をLineNumberMarginと非常によく似ています。 ShowLineNumbersが真の場合、thisのようにLineNumberMarginが作成されます。分離されたコントロール内のリストボックス項目の行番号を描画する

とにかく、私は彼らがそれをやり遂げる方法を見て、理解しました。そして今、私はListBox(とそのアイテム)を描画のソースとして使って同様のものを適用しようとしています。

私のコントロールは次のように動作します。ListBoxの左側にドッキングされた分離されたItemsControlがあります。各ItemsControlのアイテムはUIElementです。 DesignerLineNumberMarginはItemsControlの項目の1つであり、ListBoxのItemsSourceが設定されている場合、ListBoxをDesignerLineNumberMarginに添付します。 DesignerLineNumberMarginがレンダリングされると、ListBoxのアイテムを繰り返し処理し、行番号を描画します。

DesignerLineNumberMargin.cs

public interface IMetadataAware 
{ 
    void Attach(ItemsControl control); 
    void Detach(ItemsControl control); 
} 

public class DesignerLineNumberMargin : FrameworkElement, IMetadataAware 
{ 
    private ItemsControl control; 
    private Typeface typeface; 
    private double emSize; 
    private int maxLineNumberLength = 2; 

    static DesignerLineNumberMargin() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(DesignerLineNumberMargin), 
      new FrameworkPropertyMetadata(typeof(DesignerLineNumberMargin))); 
    } 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     typeface = CreateTypeface(); 
     emSize = (double)GetValue(TextBlock.FontSizeProperty); 

     var text = CreateText(new string('9', maxLineNumberLength)); 

     return new Size(text.Width, 0); 
    } 

    private FormattedText CreateText(string text) 
    { 
     return 
      new FormattedText(
      text, 
      CultureInfo.CurrentCulture, 
      FlowDirection.LeftToRight, 
      typeface, 
      emSize, 
      (Brush)GetValue(Control.ForegroundProperty)); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     if (control == null) 
      return; 

     var renderSize = RenderSize; 
     var foreground = (Brush)GetValue(Control.ForegroundProperty); 

     for (int index = 0; index < control.Items.Count; index++) 
     { 
      var item = control.Items[index]; 
      var container = (FrameworkElement)control.ItemContainerGenerator.ContainerFromItem(item); 

      var text = CreateText((index + 1).ToString(CultureInfo.CurrentCulture)); 
      //var y = container.Height; 
      var y = RenderSize.Height/(double)control.Items.Count; 

      drawingContext.DrawText(text, new Point(renderSize.Width - text.Width, y + index)); 
     } 
    } 

    private Typeface CreateTypeface() 
    { 
     var element = this; 
     return new Typeface(
      (FontFamily)element.GetValue(TextBlock.FontFamilyProperty), 
      (FontStyle)element.GetValue(TextBlock.FontStyleProperty), 
      (FontWeight)element.GetValue(TextBlock.FontWeightProperty), 
      (FontStretch)element.GetValue(TextBlock.FontStretchProperty)); 
    } 

    public void Attach(ItemsControl control) 
    { 
     this.control = control; 

     var descriptor = TypeDescriptor.GetProperties(control)["ItemsSource"]; 
     descriptor.AddValueChanged(control, OnItemsSourceChanged); 
    } 

    private void OnItemsSourceChanged(object sender, EventArgs e) 
    { 
     if (this.control.ItemsSource is INotifyCollectionChanged) 
      (this.control.ItemsSource as INotifyCollectionChanged).CollectionChanged += CollectionChanged; 
    } 

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     InvalidateVisual(); 
    } 

    public void Detach(ItemsControl control) 
    { 
     if (this.control == control) 
     { 
      var descriptor = TypeDescriptor.GetProperties(control)["ItemsSource"]; 
      descriptor.RemoveValueChanged(control, OnItemsSourceChanged); 

      if (this.control.ItemsSource is INotifyCollectionChanged) 
       (this.control.ItemsSource as INotifyCollectionChanged).CollectionChanged -= CollectionChanged; 
      this.control = null; 
     } 

     InvalidateVisual(); 
    } 
} 

問題私にとってy座標を考え出すされています。 OnRenderは私がListBoxItemHeightを知らないと呼ばれている時:高さは、ActualHeight、DesiredSizeをは常に0

enter image description here

任意の洞察力のですか?

答えて

0

あなたのMeasureOverride()は、WidthのみのSizeが返されますが、Heightはゼロに設定されているからです。

return new Size(text.Width, text.Height); 

はにreturn文を変更してください

関連する問題