2012-04-03 195 views
6

对于我的WPF的形​​式记录用户的行为,我添加了一些全球性的事件处理程序有没有wpf UIElement的唯一标识符?

我想到底是哪控制火灾事件日志,是有在ASP.Net一个WPF UIElement像客户端Id一些独特的标识?

+1

您是否试过[FrameworkElement.Name](http://msdn.microsoft.com/zh-cn/library/system.windows.frameworkelement.name.aspx)属性? – DmitryG 2012-04-03 15:11:35

+0

是啊德米特里,但名称可以是空的,我不想把每个控件上的名字专门用于日志目的 – 2012-04-03 15:14:47

+0

@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

回答

2

似乎我找到了我的问题的答案,答案是否,现在的方式来做到这一点,正如MSDN在这里(http://msdn.microsoft.com/en-us/magazine/dd483216.aspx)

请注意,顶级窗口控件定义不包含 名称属性。这很重要,因为我们很快就会看到,当您编写测试自动化时,使用MUIA库获取对 控件的引用的一种简单方法是访问由编译器从编译器生成的AutomationId属性 控件的Name属性。 没有XAML名称属性的控件将不会收到 AutomationId属性。这个想法是考虑应用程序设计问题 (如安全性,可扩展性和测试自动化)的重要性的一个特定的低级示例。

0

你只是在寻找添加Namex: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对象。它意味着存储任意信息,所以如果你愿意,你可以使用它作为唯一的标识符。

+0

感谢回答@my,但名称不是我正在寻找的,起初我不想给出所有UI控件用于记录的递归命名,其次它可能不能用于有很多编辑控件的网格单元格模板... – 2012-04-03 15:21:59

8

为什么你不使用哈希码。

您可以比较值,以确保它们是同一个对象,它易与.GetHashCode()


编辑,让他们

显然,每次运行程序时,这是不同的,所以实际上,这是一个糟糕的主意,除非你想每次登录进程都更新日志。虽然可能

不过我的意思是,你可以在创建日志的时间每个对象的哈希值,但我不知道我是否喜欢

+0

我测试过,问题是GetHashCode()仅适用于该会话。如果关闭应用程序并重新启动UI元素,将全部获得新的HashCodes。但仍然+1。 – Paparazzi 2012-04-03 15:36:11

+0

@ExitMusic,至少在应用程序重新启动后,GetHashCode将被更改,这将使日志不可用...我想要有更稳定的标识符 – 2012-04-03 15:36:50

+0

哈希值不是唯一的。 – 2017-06-27 19:40:06

0

我相信,用于记录用户的操作,您可以使用UIAutomation treeAutomationElement.AutomationId属性,因为默认情况下,所有标准UI控件都支持此方法。许多第三方控件也支持其元素的AutomationId(例如网格单元格)。 AutomationId对于创建测试自动化脚本非常有用。

+0

嗯...似乎AutomationId也应该设置,如果它没有设置,它返回名称,在我们的情况是空的...我想没办法做我在找什么... – 2012-04-03 15:48:30

1

你可以这样做的一种方法是使用自定义属性。是这样的...

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(...) 

在一些方法当事件在控制燃煤和嵌入您的日志记录代码存在。这种模式并不是最好的,因为你在贯穿横切关注点,使得某些类型的面向方面的编程方法更好......但是我又离题了,它超出了本文的范围......但是你得到了理念。

希望这会有所帮助。

+0

为什么我需要一个属性?我可以设置我的用户界面元素的所有名称属性,我只想找到一种没有设置任何东西的方法,因为它可能在winform中 – 2012-04-20 20:47:43