对于我的WPF的形式记录用户的行为,我添加了一些全球性的事件处理程序有没有wpf UIElement的唯一标识符?
我想到底是哪控制火灾事件日志,是有在ASP.Net一个WPF UIElement
像客户端Id一些独特的标识?
对于我的WPF的形式记录用户的行为,我添加了一些全球性的事件处理程序有没有wpf UIElement的唯一标识符?
我想到底是哪控制火灾事件日志,是有在ASP.Net一个WPF UIElement
像客户端Id一些独特的标识?
似乎我找到了我的问题的答案,答案是否,现在的方式来做到这一点,正如MSDN在这里(http://msdn.microsoft.com/en-us/magazine/dd483216.aspx)
请注意,顶级窗口控件定义不包含 名称属性。这很重要,因为我们很快就会看到,当您编写测试自动化时,使用MUIA库获取对 控件的引用的一种简单方法是访问由编译器从编译器生成的AutomationId属性 控件的Name属性。 没有XAML名称属性的控件将不会收到 AutomationId属性。这个想法是考虑应用程序设计问题 (如安全性,可扩展性和测试自动化)的重要性的一个特定的低级示例。
你只是在寻找添加Name
或x:Name
,使Window
/UserControl
/Page
暴露控制类的其余部分使用指定的名称。
<Window ...>
<Grid>
...
<!-- These controls are named, so you can access them directly by name -->
<Button x:Name="btnMyNamedButton" ... />
<Button Name="btnMyOtherNamedButton" ... />
<!-- This control is not named, so you can not directly access it by name -->
<Button ... />
<Grid>
</Window>
public partial class MyWindow : Window
{
public MyWindow()
{
InitializeComponent();
//btnMyNamedButton can be accessed
//btnMyOtherNamedbutton can also be accessed
//The third button can be accessed, but not directly by name.
}
}
此外,您还可以随时使用FrameworkElement.Tag对象。它意味着存储任意信息,所以如果你愿意,你可以使用它作为唯一的标识符。
感谢回答@my,但名称不是我正在寻找的,起初我不想给出所有UI控件用于记录的递归命名,其次它可能不能用于有很多编辑控件的网格单元格模板... – 2012-04-03 15:21:59
为什么你不使用哈希码。
您可以比较值,以确保它们是同一个对象,它易与.GetHashCode()
显然,每次运行程序时,这是不同的,所以实际上,这是一个糟糕的主意,除非你想每次登录进程都更新日志。虽然可能
不过我的意思是,你可以店在创建日志的时间每个对象的哈希值,但我不知道我是否喜欢
我测试过,问题是GetHashCode()仅适用于该会话。如果关闭应用程序并重新启动UI元素,将全部获得新的HashCodes。但仍然+1。 – Paparazzi 2012-04-03 15:36:11
@ExitMusic,至少在应用程序重新启动后,GetHashCode将被更改,这将使日志不可用...我想要有更稳定的标识符 – 2012-04-03 15:36:50
哈希值不是唯一的。 – 2017-06-27 19:40:06
我相信,用于记录用户的操作,您可以使用UIAutomation tree和AutomationElement.AutomationId属性,因为默认情况下,所有标准UI控件都支持此方法。许多第三方控件也支持其元素的AutomationId(例如网格单元格)。 AutomationId对于创建测试自动化脚本非常有用。
嗯...似乎AutomationId也应该设置,如果它没有设置,它返回名称,在我们的情况是空的...我想没办法做我在找什么... – 2012-04-03 15:48:30
你可以这样做的一种方法是使用自定义属性。是这样的...
的UIElement
要记录(用户控件为例):
[UserInterfaceID(ID = "{F436E9B3-C2F6-4CF8-8C75-0A2A756F1C74}")]
public partial class MyUserControl : UserControl
{
InitializeComponent();
// or whatever...
}
然后,你需要自定义属性类
[System.AttributeUsage(AttributeTargets.Class)]
public class UserInterfaceIDAttribute : Attribute
{
public Guid ID { get; set; }
}
在你的代码
现在,你可以做这样的事情:
MyUserControl control = new MyUserControl();
foreach(object att in control.GetCustomAttributes(typeof(UserInterfaceAttribute),false))
{
UserInterfaceAttribute uiAtt = (UserInterfaceAttribute)att;
Guid theID = uiAtt.ID;
}
因为你是标记控制与属性在代码,无论您杀死/启动应用程序多少次,唯一标识符都不会改变。
当然这是一个基本的例子,显示了如何访问ID,但你可能会想使用某种类型的面向方面编程。我使用Castle Windsor拦截器来完成这种事情,但这不在本文的讨论范围之内。
理想情况下,当有某种事件被触发时,您将访问此ID。使用拦截器允许您在调用捕获方法调用之前进行捕获方法调用,其中您可以查找上面显示的ID并记录操作。另外,您也可以只使用
this.GetCustomAttributes(...)
在一些方法当事件在控制燃煤和嵌入您的日志记录代码存在。这种模式并不是最好的,因为你在贯穿横切关注点,使得某些类型的面向方面的编程方法更好......但是我又离题了,它超出了本文的范围......但是你得到了理念。
希望这会有所帮助。
为什么我需要一个属性?我可以设置我的用户界面元素的所有名称属性,我只想找到一种没有设置任何东西的方法,因为它可能在winform中 – 2012-04-20 20:47:43
您是否试过[FrameworkElement.Name](http://msdn.microsoft.com/zh-cn/library/system.windows.frameworkelement.name.aspx)属性? – DmitryG 2012-04-03 15:11:35
是啊德米特里,但名称可以是空的,我不想把每个控件上的名字专门用于日志目的 – 2012-04-03 15:14:47
@ArsenMkrt,[PersistId](http://msdn.microsoft.com/en-us/library/ system.windows.uielement.persistid.aspx)属性似乎是你要找的。唉,它现在已经过时,显然没有替代品。也许你可以回到自己生成唯一的标识符,在这种情况下请参阅[这个问题](http://stackoverflow.com/q/750947/464709)。 – 2012-04-03 15:18:01