Frage

Ich möchte auf der Spitze eines Textblock ziehen zu können, und haben einen Weg gefunden, dies zu tun gefunden, aber ich kann die Zeichnung nicht entfernen, sobald es da ist. Hier ist der Code.

   public class DerivedTextBlock : TextBlock {

      public Boolean DrawExtra {
         get { return (Boolean)GetValue(DrawExtraProperty); }
         set { SetValue(DrawExtraProperty, value); }
      }

      // Using a DependencyProperty as the backing store for DrawExtra.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty DrawExtraProperty =
          DependencyProperty.Register("DrawExtra", typeof(Boolean), typeof(DerivedTextBlock), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsArrange));

      public DrawingVisual DrawingVisual { get; set; }

      public DerivedTextBlock() {
         DrawingVisual = this.CreateDrawingVisualRectangle();
      }

      protected override int VisualChildrenCount {
         get {
            //if we want to draw our extra info, add one to
            // our visualChildrenCount, usually with a textblock it is 0
            if (DrawExtra) {
               return base.VisualChildrenCount + 1;
            }
            else {
               return base.VisualChildrenCount;
            }
         }
      }

      protected override Visual GetVisualChild(int index) {
         return DrawingVisual;
      }

      // Create a DrawingVisual that contains a rectangle.
      private DrawingVisual CreateDrawingVisualRectangle() {
         DrawingVisual drawingVisual = new DrawingVisual();

         // Retrieve the DrawingContext in order to create new drawing content.
         DrawingContext drawingContext = drawingVisual.RenderOpen();

         // Create a rectangle and draw it in the DrawingContext.
         Rect rect = new Rect(new Point(10.0, 0), new Size(10.0 / 2.0, 10));
         drawingContext.DrawRectangle(Brushes.LightBlue, (Pen)null, rect);

         // Persist the drawing content.
         drawingContext.Close();

         return drawingVisual;
      }
   }

Reason Ich möchte, dies zu tun: Wir haben eine Datenraster mit einer Menge von Zellen, die Anzeige jede Zelle Text. Wir zeigen einige Validierungs Informationen zu den Zellen und wir tun dies, indem Sie eine Vorlage mit einem Textblock mit und einigen in einem Raster hosten Wegen. der Aufwand für diese sorgt für zusätzliche Elemente der visuellen Struktur und wenn wir (auf Laden, Schaltfenster oder auf einer Art) neu zeichnen müssen dauert es viel länger je mehr Elemente in der visuellen Struktur. wenn es nur ein Textblock ist, ist es etwa 1/3 - 1/2 schneller als mit einem Raster die Steuerung aufweist. So möchten wir unsere Validierungs Sachen oben auf der Textbox rechts ziehen.

War es hilfreich?

Lösung

Ihre Probleme sind:

  1. GetVisualChild () sollte zurückgeben base.GetVisualChild (Index), außer wenn der Index == base.VisualChildrenCount.
  2. Sie haben vergessen AddVisualChild () aufzurufen, wenn DrawingExtra wahr wird oder DrawingVisual ändert
  3. Sie haben vergessen RemoveVisualChild () aufzurufen, wenn DrawingExtra falsch wird oder DrawingVisual ändert

Sie können fix # 2 und # 3 durch einen PropertyChangedCallback auf DrawingExtra Einstellung und das Hinzufügen von Code zu dem Setter von DrawingVisual.

Erläuterung: Es ist die AddVisualChild () Aufruf, der fügt tatsächlich die visuelle zum Baum. Was geschieht, ist, dass Ihre visuelle gefunden und angezeigt werden „versehentlich“ wegen Ihres Fehlers in GetVisualChild (), aber es ist nicht richtig in die visuelle Struktur verknüpft ist, so werden Sie viele Probleme auftreten.

Aktualisieren

bearbeiten ich Code wie oben beschrieben, und es funktionierte perfekt. Hier sind die Änderungen:

...
      {
        PropertyChangedCallback = (obj, e) =>
          {
            var textBlock = (DerivedTextBlock)obj;
            if((bool)e.OldValue) textBlock.RemoveVisualChild(textBlock.DrawingVisual);
            if((bool)e.NewValue) textBlock.AddVisualChild(textBlock.DrawingVisual);
          }
      });

  public DrawingVisual DrawingVisual
  {
    get { return _drawingVisual; }
    set
    {
      if(DrawExtra) RemoveVisualChild(_drawingVisual);
      _drawingVisual = value;
      if(DrawExtra) AddVisualChild(_drawingVisual);
    }
  }
  private DrawingVisual _drawingVisual;

...

  protected override int VisualChildrenCount
  {
    get { return base.VisualChildrenCount + (DrawExtra ? 1 : 0); }
  }

  protected override Visual GetVisualChild(int index)
  {
    return index==base.VisualChildrenCount ? DrawingVisual : base.GetVisualChild(index);
  }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top