Domanda

Voglio essere in grado di attingere alla parte superiore di un TextBlock, e hanno trovato un modo per fare questo, ma non è possibile rimuovere il disegno una volta che è lì. Ecco il codice.

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

motivo che voglio fare questo: Abbiamo un datagrid con un sacco di celle, ogni cella visualizzazione del testo. vi mostriamo alcune informazioni di convalida sulle cellule e lo facciamo utilizzando un modello con un blocco di testo e alcuni percorsi Hosten in una griglia. l'overhead di questo aggiunge elementi extra all'albero visiva e quando dobbiamo ridisegnare (sul caricamento, passaggio finestre o su una specie) richiede molto più lunghi più elementi nella struttura visiva. quando è solo un blocco di testo è di circa 1/3 - 1/2 più veloce di avere il controllo con una griglia. Così vorremmo attirare la nostra roba convalida proprio sopra la casella di testo.

È stato utile?

Soluzione

I tuoi problemi sono:

  1. GetVisualChild () dovrebbe restituire base.GetVisualChild (indice) tranne quando Indice == base.VisualChildrenCount.
  2. Hai dimenticato di chiamare AddVisualChild () quando DrawingExtra diventa vera o DrawingVisual modifiche
  3. Hai dimenticato di chiamare RemoveVisualChild () quando DrawingExtra diventa falsa o DrawingVisual modifiche

È possibile risolvere # 2 e # 3 impostando un PropertyChangedCallback su DrawingExtra e l'aggiunta di codice per il setter di DrawingVisual.

Spiegazione: E 'la chiamata AddVisualChild () che aggiunge in realtà la visuale verso l'albero. Quello che sta accadendo è che il vostro visiva è di essere trovati e visualizzati "accidentalmente" a causa del vostro errore nel GetVisualChild (), ma non viene adeguatamente collegato nella struttura visiva in modo che si incontrano molti problemi.

Aggiorna

Ho modificato il codice come descritto in precedenza, e ha funzionato perfettamente. Ecco le modifiche:

...
      {
        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);
  }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top