2015-01-06 3 views
1

Я использую Adorner для размещения треугольника индикатора в выбранных ячейках WPF DataGrid (тот же эффект, который вы получаете при вставке комментария в ячейку в Excel). К сожалению, я получаю случайные рекламные ролики, где они не должны.WPF DataGrid и Adorners

Предположим, что есть 3 ячейки, у которых должен быть Adorner; Я получаю 3 дополнительных ячейки, которые также имеют Adorner. Я доказал, что только 3 создаются в коде, хотя их 6. Я создаю/удаляю Adorners в событии ElementGenerated.

Дополнительные экземпляры всегда находятся на ячейках, которые еще не находятся в визуальной области сетки, и поэтому я уверен, что проблема связана с виртуализацией столбцов сетки и что сетка повторно использует ячейки, а не создавая новые, и как таковое событие ElementGenerated не запускается снова, и Adorner не удаляется там, где он не нужен.

Я не могу найти событие, которое я мог бы использовать, когда ячейка повторно используется. Любые предложения были бы с благодарностью получены.

Это код треугольника Adorner: -

public class TriangleAdorner : Adorner 
{ 
    private readonly double _offsetX; 
    private readonly double _offsetY; 

    public TriangleAdorner(UIElement adornedElement) 
     : this(adornedElement, 0, 0) 
    { 
    } 

    public TriangleAdorner(UIElement adornedElement, double offsetX, double offsetY) 
     : base(adornedElement) 
    { 
     _offsetX = offsetX; 
     _offsetY = offsetY; 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     //Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize); 

     // all examples seem to use the above but this didn't get the adorner in the correct place for me 
     Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize); 

     PointCollection myPointCollection = new PointCollection 
               { 
                new Point(adornedElementRect.TopLeft.X + 6 + _offsetX, adornedElementRect.TopLeft.Y + 1 + _offsetY), 
                new Point(adornedElementRect.TopLeft.X + 1 + _offsetX, adornedElementRect.TopLeft.Y + 1 + _offsetY), 
                new Point(adornedElementRect.TopLeft.X + 1 + _offsetX, adornedElementRect.TopLeft.Y + 6 + _offsetY) 
               }; 

     StreamGeometry streamGeometry = new StreamGeometry(); 
     using (StreamGeometryContext geometryContext = streamGeometry.Open()) 
     { 
      geometryContext.BeginFigure(myPointCollection[0], true, true); 
      PointCollection points = new PointCollection 
             { 
              myPointCollection[1], 
              myPointCollection[2] 
             }; 
      geometryContext.PolyLineTo(points, true, true); 
     } 

     drawingContext.DrawGeometry(Brushes.Red, new Pen(Brushes.Red, 0), streamGeometry); 

    } 

    protected override Size MeasureOverride(Size constraint) 
    { 
     var result = base.MeasureOverride(constraint); 

     InvalidateVisual(); 
     return result; 
    } 

И событие, которое добавляет/удаляет: -

private void DataGrid_ElementGenerated(object sender, ElementGeneratedEventArgs e) 
{ 
     FrameworkElement element = (FrameworkElement) e.DataGridCell; 
     if (element == null) return; 

     AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(element); 
     if (adornerLayer != null) 
     { 

      if (CellAdornerRequired()) 
      { 
       Adorner[] children = adornerLayer.GetAdorners(element); 
       if (children == null || !children.Any()) 
       { 
        adornerLayer.Add(new TriangleAdorner(element)); 
       } 
      } 
      else 
      { 
       Adorner[] children = adornerLayer.GetAdorners(element); 
       if (children != null && children.Any()) 
       { 
        foreach (var adorner in children) 
        { 
         adornerLayer.Remove(adorner); 
        } 
       } 
      } 
     } 
    } 

ответ

0

Вы можете использовать DataGrid.LoadingRow и DataGrid.UnloadingRow события, чтобы получить уведомление, когда строка повторно используется виртуализацией. К сожалению, я не думаю, что вы можете добраться до них.

Вы можете попытаться прикрепить к DataGridCell.Loaded и DataGridCell.DataContextChanged событиям для создания и обновления ваших украшений.

+0

Дополнительные символы отображаются в столбцах, находящихся за пределами области просмотра. DataGrid не загружает ячейки в этих столбцах, пока они не потребуются. Я не упомянул, что Grid - это настроенная версия WPF DataGrid и что есть специальный столбец шаблона. Я создал Guid внутри класса TriangleAdorner, чтобы я мог идентифицировать adorner в событии OnRender. Кажется, что один и тот же экземпляр adorner отображается в нескольких местах. Спасибо за ваш ответ. – EzaBlade

 Смежные вопросы

  • Нет связанных вопросов^_^