Как изменить цвет DrawingVisual на MouseHit

Следующий код представляет собой адаптацию примера кода на странице 502 Адама Натана, выпуск WPF 4.5.

Следуя совету, я создал класс, который «размещает» список DrawingVisuals, тем самым делая их отображаемыми. Это работало до сих пор.

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

С включенными операторами Trace.WriteLine я вижу, что соответствующая строка

      drw.Brush = Brushes.Red;

достигается, и после этого свойство Brush получает новое значение. Но: отображение не меняется, после щелчка DrawingVisual по-прежнему остается желтым (это был цвет кисти, используемый при создании).

Что я могу/должен сделать здесь? (Я абсолютный новичок в WPF).

Заранее спасибо за все ответы!

          public partial class VisualHostClass : FrameworkElement
    {
        public VisualHostClass()
        {
 
        }

        public List<DrawingVisual> myVisuals = new List<DrawingVisual>();

        public void AddVisual(DrawingVisual dvs)
        {
            myVisuals.Add(dvs);
            AddVisualChild(dvs);
            AddLogicalChild(dvs);

        }

        protected override int VisualChildrenCount
        {
            get { return myVisuals.Count; }
        }

        protected override Visual GetVisualChild(int index)
        {
            if (index < 0 || index >= myVisuals.Count)
            {
                throw new ArgumentOutOfRangeException("index");
            }

            return myVisuals[index];
        }

        public void removeAllChilds()
        {
            foreach (DrawingVisual dvs in myVisuals)
            {
                RemoveVisualChild(dvs);
                RemoveLogicalChild(dvs);
            }
            myVisuals.Clear();
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            Point location = e.GetPosition(this);

            VisualTreeHelper.HitTest(this, null,
                new HitTestResultCallback(HitTestCallback),
                new PointHitTestParameters(location));

        }

        public HitTestResultBehavior HitTestCallback(HitTestResult result)
        {
            if (result.VisualHit.GetType() == typeof(DrawingVisual))
            {
                DrawingVisual dv = result.VisualHit as DrawingVisual;

                Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());

                foreach(GeometryDrawing drw in dv.Drawing.Children)
                {
                    Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
                    
                    Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());

                    Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());

                    drw.Brush = Brushes.Red;

                    Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());

                    Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());

                }
 
            }

            return HitTestResultBehavior.Continue;
        }
    }
}

РЕДАКТИРОВАТЬ: после некоторых экспериментов сработало следующее (но меня это не удовлетворяет, так как я могу только изменить Colorиз SolidColorBrush, но не Brushсам):

         public void ChangeBrush(DrawingVisual dv)
    {
        Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());

        foreach (Drawing drw1 in dv.Drawing.Children)
        {
            if (drw1 is GeometryDrawing)
            {
                GeometryDrawing drw = drw1 as GeometryDrawing;

                Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());

                Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());

                Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());

                Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
                Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());

                // does not work
                //SolidColorBrush newBrush = new SolidColorBrush(Colors.Red);

                //newBrush.Freeze();

                //drw.Brush = newBrush;

                // works with drw.Brush already containing a SolidColorBrush
                (drw.Brush as SolidColorBrush).Color =
                    (drw.Brush as SolidColorBrush).Color == Colors.LightGoldenrodYellow ?
                    Colors.Red : Colors.LightGoldenrodYellow;

                Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());

                Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
                Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());

            }
        }


    }

Просто для протокола привожу код, где DrawingVisualпостроен и введен VisualHostClass

              PathGeometry pgnGeom = RenderPolygonWithHoles2Geometry(pgn);

        DrawingVisual dv = new DrawingVisual();

        using (DrawingContext dc = dv.RenderOpen())
        {
            SolidColorBrush brush1 = new SolidColorBrush(Colors.LightGoldenrodYellow);
            dc.DrawGeometry(brush1, null, pgnGeom);
        }

        myVisualHost.AddVisual(dv);

1 ответ

Похоже, что рисунок, созданный dc.DrawGeometry(...)является замороженным, т.е. не поддающимся изменению.

Передача моего собственного рисунка сработала для меня:

      using (var dc = dv.RenderOpen())
{
    dc.DrawDrawing(new GeometryDrawing(Brushes.LightGoldenrodYellow, null, pgnGeom));
}
Другие вопросы по тегам