WPF OnRender未在FrameworkElement上调用

问题描述

我有以下带有嵌套“视觉效果”的自定义框架元素(它只绘制了一个矩形和一些椭圆)。现在,我想在鼠标进入或离开控件时更改一些颜色。该代码将被调用,但是即使使用InvalidVisual,颜色也不会改变。知道这里有什么问题吗:

public class Dummy : FrameworkElement
{
    #region Fields

    private Ellipse _bottomLeft = new Ellipse();
    private Ellipse _bottomright = new Ellipse();
    private ContainerVisual _containerVisual = new ContainerVisual();

    private Rectangle _rect = new Rectangle();
    private Ellipse _topLeft = new Ellipse();
    private Ellipse _topRight = new Ellipse();

    #endregion Fields

    #region Constructors

    public Dummy()
    {
        Initialize();

        _containerVisual.Children.Add(_rect);
        _containerVisual.Children.Add(_topLeft);
        _containerVisual.Children.Add(_topRight);
        _containerVisual.Children.Add(_bottomLeft);
        _containerVisual.Children.Add(_bottomright);
    }

    #endregion Constructors

    #region Properties

    protected override int VisualChildrenCount
    {
        get { return _containerVisual == null ? 0 : 1; }
    }

    #endregion Properties

    #region Methods

    private void Initialize()
    {
        // Rectangle
        _rect.stroke = Brushes.Red;
        _rect.strokeThickness = 1;
        _rect.Fill = new SolidColorBrush(Colors.Transparent);
        // Ellipses
        _topLeft.strokeThickness = 1;
        _topLeft.stroke = Brushes.Red;
        _topLeft.Fill = new SolidColorBrush(Colors.Orange);
        //----------------
        _topRight.strokeThickness = 1;
        _topRight.stroke = Brushes.Red;
        _topRight.Fill = new SolidColorBrush(Colors.Orange);
        //----------------
        _bottomLeft.strokeThickness = 1;
        _bottomLeft.stroke = Brushes.Red;
        _bottomLeft.Fill = new SolidColorBrush(Colors.Orange);
        //----------------
        _bottomright.strokeThickness = 1;
        _bottomright.stroke = Brushes.Red;
        _bottomright.Fill = new SolidColorBrush(Colors.Orange);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        var diameter = 6;
        var radius = diameter / 2;
        var rectThicknessOffset = _rect.strokeThickness / 2;

        var rect = new Rect(new Point(0,0),finalSize);

        _rect.Arrange(rect);
        _topLeft.Arrange(new Rect(rect.TopLeft.X - radius + rectThicknessOffset,rect.TopLeft.Y - radius + rectThicknessOffset,diameter,diameter));
        _topRight.Arrange(new Rect(rect.TopRight.X - radius - rectThicknessOffset,rect.TopRight.Y - radius + rectThicknessOffset,diameter));
        _bottomright.Arrange(new Rect(rect.Bottomright.X - radius - rectThicknessOffset,rect.Bottomright.Y - radius - rectThicknessOffset,diameter));
        _bottomLeft.Arrange(new Rect(rect.BottomLeft.X - radius + rectThicknessOffset,rect.BottomLeft.Y - radius - rectThicknessOffset,diameter));
        return base.ArrangeOverride(finalSize);
    }

    // Provide a required override for the GetVisualChild method.
    protected override Visual GetVisualChild(int index)
    {
        if (_containerVisual == null)
        {
            throw new ArgumentOutOfRangeException();
        }
        return _containerVisual;
    }

    protected override void OnMouseEnter(MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        _rect.stroke = new SolidColorBrush(Colors.Blue);
        InvalidateVisual();
        Debug.WriteLine("Mouse Enter");
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    {
        base.OnMouseLeave(e);
        _rect.stroke = new SolidColorBrush(Colors.Green);
        InvalidateVisual();
        Debug.WriteLine("Mouse Leave");
    }

    protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
    {
        return new PointHitTestResult(this,hitTestParameters.HitPoint);
    }

    #endregion Methods
}

解决方法

尝试将对InvalidateVisual的呼叫替换为对MeasureArrange的呼叫:

protected override void OnMouseLeave(MouseEventArgs e)
{
    base.OnMouseLeave(e);
    _rect.Stroke = new SolidColorBrush(Colors.Green);
    Measure(Size.Empty);
    Arrange(new Rect(DesiredSize));
    Debug.WriteLine("Mouse Leave");
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...