我的装饰品定义如下:
private class ErrorAdorner : Adorner
{
private readonly Border _errorBorder;
public ErrorAdorner(UIElement adornedElement)
: base(adornedElement)
{
_errorBorder = new Border();
_errorBorder.BorderThickness = new Thickness(2);
_errorBorder.BorderBrush = Brushes.Red;
Image img = new Image();
img.HorizontalAlignment = HorizontalAlignment.Right;
img.VerticalAlignment = VerticalAlignment.Center;
img.Stretch = Stretch.None;
Binding imgBinding = new Binding
{
Source = adornedElement,
Path = new PropertyPath(IconProperty)
};
img.SetBinding(Image.SourceProperty, imgBinding);
Binding ttBinding = new Binding
{
Source = adornedElement,
Path = new PropertyPath(ErrorMessageProperty)
};
img.SetBinding(ToolTipProperty, ttBinding);
_errorBorder.Child = img;
}
protected override Size MeasureOverride(Size constraint)
{
AdornedElement.Measure(constraint);
return AdornedElement.RenderSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
_errorBorder.Arrange(new Rect(finalSize));
return finalSize;
}
protected override Visual GetVisualChild(int index)
{
if (index == 0)
return _errorBorder;
throw new ArgumentOutOfRangeException("index");
}
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
}
ErrorMessage
和Icon
是在封闭类(ErrorProvider
)中声明的附加属性。当ErrorMessage
属性设置为非空值时,会将adorner添加到元素中。
我的问题是,当正确渲染装饰时,当我将鼠标移到它上面时,图像上的ToolTip
不会显示。我知道这不是一个绑定问题:当我用Snoop检查控件时,我可以看到ToolTip
属性具有预期值。我怀疑这个问题与命中测试有关,因为我无法在adorner中收到任何鼠标相关事件... IsHitTestVisible
属性设置为true,所以我不知道明白为什么我没有收到这些活动。
有什么想法吗?
答案 0 :(得分:2)
好的,这也是我之前咬过的东西。当您定义自己的可视化树时,仅仅返回可视化子项是不够的,还需要告诉WPF您已添加它们。在构造函数的最后添加:
this.AddVisualChild(_errorBorder);
this.AddLogicalChild(_errorBorder);
您还应该实现LogicalChildren
属性:
protected override System.Collections.IEnumerator LogicalChildren
{
get
{
yield return _errorBorder;
}
}
如果您有多个孩子,我会使用UIElementCollection
。它会将它们添加到可视树和逻辑树中,您可以在LogicalChildren
,VisualChildrenCount
和GetVisualChild
覆盖中使用它。