问题描述
我有以下带有嵌套“视觉效果”的自定义框架元素(它只绘制了一个矩形和一些椭圆)。现在,我想在鼠标进入或离开控件时更改一些颜色。该代码将被调用,但是即使使用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
的呼叫替换为对Measure
和Arrange
的呼叫:
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");
}