我们的应用程序有一个画布,我们在其中添加绘图视觉效果(如线条、多边形等)
// sample code
var canvas = new Canvas(); // create canvas
var visuals = new VisualCollection(canvas); // link the canvas to the visual collection
visuals.Add(new DrawingVisual()); // add the visuals to the canvas
visuals.Add(new DrawingVisual());
我们的目标是通过自动化将这些视觉对象添加到画布中,并验证它们是否正确添加。我们使用基于Microsoft UIAutomation的框架。
当使用像“检查”这样的工具来检查视觉结构时,我找不到画布。做了一些研究,发现你需要覆盖UIElement
中的OnCreateAutomationPeer
方法,并返回适用的AutomationPeer
对象才能在自动化中看到它。
进行了更改,现在我可以看到画布,但是我仍然看不到画布下添加的任何视觉效果。
有人能帮我理解问题是什么吗?
尝试过的事情/替代方案:
DrawingVisual
不是从UIElement
派生的,我无法将UIElement
添加到Canvas. VisualCollection
。
从UIAutomation中只能看到UIElement(如您所见,OnCreateAutomationPeer从此类开始,而不是从Visual类开始)。
因此,如果您希望UIAutomation可以使用它,则需要将UIElement(或像FrameworkElement一样派生)添加到画布中。
您可以像这里描述的那样创建自己的类:使用DrawingVisual Object或使用自定义UserControl或使用适合您需要的现有类,但它必须以某种方式派生自UIElement。
一旦你有了一个好的类,你可以使用默认的AutomationPeer或覆盖该方法并更密切地适应。
如果你想保留Visual对象,一种解决方案是修改包含对象(但它仍然需要从UIElement派生)。例如,这里如果我按照链接中的文章,我可以编写一个自定义的包含对象(而不是你的示例代码的画布,所以你可能必须稍微适应),如下所示:
public class MyVisualHost : UIElement
{
public MyVisualHost()
{
Children = new VisualCollection(this);
}
public VisualCollection Children { get; private set; }
public void AddChild(Visual visual)
{
Children.Add(visual);
}
protected override int VisualChildrenCount
{
get { return Children.Count; }
}
protected override Visual GetVisualChild(int index)
{
return Children[index];
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new MyVisualHostPeer(this);
}
// create a custom AutomationPeer for the container
private class MyVisualHostPeer : UIElementAutomationPeer
{
public MyVisualHostPeer(MyVisualHost owner)
: base(owner)
{
}
public new MyVisualHost Owner
{
get
{
return (MyVisualHost)base.Owner;
}
}
// a listening client (like UISpy is requesting a list of children)
protected override List<AutomationPeer> GetChildrenCore()
{
List<AutomationPeer> list = new List<AutomationPeer>();
foreach (Visual visual in Owner.Children)
{
list.Add(new MyVisualPeer(visual));
}
return list;
}
}
// create a custom AutomationPeer for the visuals
private class MyVisualPeer : AutomationPeer
{
public MyVisualPeer(Visual visual)
{
}
// here you'll need to implement the abstrat class the way you want
}
}