使用 Caliburn.Micro 实现 WPF UI 自动化?

发布于 2024-10-29 06:29:20 字数 1571 浏览 7 评论 0原文

我正在尝试为使用 Caliburn.Micro白色。我正在使用 CM 的内置约定将我的控件绑定到视图模型的属性和方法。我还使用了Conductor 类,这样我就可以在单个屏幕上看到多个视图。这通常意味着屏幕上的多个控件最终可能具有相同的 x:Name 值。它只会绑定到不同的视图模型。我想要做什么的一个好主意可以在 HelloScreens 示例应用程序中看到与CM

我遇到的问题是,我将拥有多个具有相同 x:Name 属性的 XAML 元素,以便 CM 可以为我处理所有绑定工作。不幸的是,这意味着多个 UIItem 对象将具有相同的 UI 自动化 ID。例如,我发现使用 x:Name="DisplayName" 获取不同 TextBlock 元素的唯一方法是进行如下调用:

SearchCriteria criteria = SearchCriteria.ByAutomationId("DisplayName").AndIndex(1);
WPFLabel label = myWindow.Get<WPFLabel>(criteria);

这意味着我的测试需要知道不同控件在屏幕上放置的确切顺序,这看起来很脆弱。只需添加另一个视图模型,我就可以看到我的测试全部中断。

  • 除了使用 x:Name 属性之外,还有其他方法可以指定自动化 ID 吗?
  • 如果我直接使用 UI 自动化框架而不是使用 White 会更容易吗?
  • 或者,我真的必须放弃 CM 基于约定的绑定并为每个唯一的 x:Name 值并手动绑定它们吗?

已更新

为了澄清我所说的同时显示多个视图的含义,这是我的总体布局。我有我的 ShellViewModel,它是从 Conductor.Collection.OneActive 派生的。然后我的视图有一个 ItemsControl ,它绑定到 shell 视图模型的 Items 属性。每个项目模板都显示一个按钮,用于将特定的 IScreen 加载到 shell 视图上的 ContentControl 中。因此,如果我尝试查找带有 x:Name="DisplayName" 的元素,我会在 shell 视图上找到标签,在 ItemsControl 中的按钮上找到标签以及 ContentControl 内的标签。

I am attempting to write some UI automation tests for a WPF application that is using Caliburn.Micro and White. I am using CM's builtin conventions to bind my controls to the view model's properties and methods. I am also using Conductor classes so that I may have multiple views visible on a single screen. This generally means that multiple controls on a screen can end up having the same x:Name value. It will just get bound to a different view model. A good idea of what I am trying to do can be seen in the HelloScreens sample application that comes with CM.

The problem that I am running in to is that I will have multiple XAML elements with the same x:Name attribute so that CM can handle all of the binding work for me. This unfortunately means that multiple UIItem objects will have the same UI Automation ID. The only way I have found to get, for instance, different TextBlock elements with x:Name="DisplayName" is to make a call such as the following:

SearchCriteria criteria = SearchCriteria.ByAutomationId("DisplayName").AndIndex(1);
WPFLabel label = myWindow.Get<WPFLabel>(criteria);

This means my tests need to know the exact order that different controls are placed on the screen, which seems very brittle. I can see my tests all breaking just by adding another view model.

  • Is there a way to specify the Automation ID other than using the x:Name attribute?
  • Would this be easier if I used the UI Automation framework directly instead of using White?
  • Or, do I really have to forego CM's convention based binding and give everyting unique x:Name values and bind them by hand?

UPDATED

To clarify what I mean by having multiple views visible at once, here is my general layout. I have my ShellViewModel which I derive from Conductor<IScreen>.Collection.OneActive. Then my view has an ItemsControl that is bound to the shell view model's Items property. Each item template shows a button that is meant to load that specific IScreen into a ContentControl that is on the shell's view. So, If I try to look for an element with x:Name="DisplayName", I have the label on the shell view, the label on the button in the ItemsControl as well as a label inside of the ContentControl.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帥小哥 2024-11-05 06:29:20

虽然 AutomationId 默认情况下来自 x:Name 属性,但您可以通过设置 AutomationProperties.AutomationId

Whilst the AutomationId by default comes from the x:Name attribute, you can override it by setting AutomationProperties.AutomationId.

你是暖光i 2024-11-05 06:29:20

一种选择可能是更改 ViewModelBinder 类型上的 BindPropertiesBindActions 委托,以使用其名称根据视图而更改的控件名称。他们属于哪一个。

例如,您可以选择将视图名称作为前缀添加到可能在其他视图中具有重复名称的每个控件。因此,DisplayName 可能会变为 ListViewDisplayNameContentViewDisplayName

在继续处理控件之前,可以删除从控件名称到并包括单词“View”的任何文本,以形成干净的控件名称。

One option may be to alter the BindProperties and BindActions delegates on the ViewModelBinder type to work with control names whose names are altered based on the view in which they belong.

For example, you could optionally add the view name as a prefix to each control that is likely to have duplicate names in other views. So DisplayName could become ListViewDisplayName, and ContentViewDisplayName.

Any text from the control name up to and including the word 'View' could be stripped to form the clean control name before continuing processing the control.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文