是否有任何wpf UIElement的唯一标识符?

时间:2012-04-03 15:08:03

标签: c# wpf wpf-controls uielement

为了记录我的WPF表单中的用户操作,我添加了一些全局事件处理程序

我想准确记录哪个控件触发事件,是否有像ASP.Net中的ClientId这样的wpf UIElement的唯一标识符?

7 个答案:

答案 0 :(得分:11)

为什么不使用哈希码。

您可以比较这些值以确保它们是同一个对象,并且可以通过.GetHashCode()轻松获取它们


修改

显然每次运行程序时都会有所不同,所以实际上这绝对是一个坏主意,除非你想在每次记录进程时更新日志。仍然可能

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

答案 1 :(得分:2)

似乎我找到了回答我的问题,答案是否定的,现在就这样做了,正如MSDN中所述(http://msdn.microsoft.com/en-us/magazine/dd483216.aspx)

  

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

答案 2 :(得分:1)

您可以使用自定义属性执行此操作。像这样......

您要记录的UIElement(例如UserControl):

[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 Interceptors完成了这种事情,但这不属于本文的范围。

理想情况下,当某种类型的事件被触发时,您将访问此ID。使用拦截器允许您在调用之前进行捕获方法调用,其中您可以如上所示查找ID并记录操作。或者,您可以使用

this.GetCustomAttributes(...)

在某些方法中,在控件上触发事件并在其中嵌入Logging代码。这种模式并不是最好的,因为你在制作某种类型的面向方面编程方法时会产生跨领域的关注......但是我再次离题,这超出了这篇文章的范围......但是你得到了想法。

希望这有帮助。

答案 3 :(得分: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对象。这意味着存储任意信息,因此如果您愿意,可以将其用作唯一标识符。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

请参阅FrameworkElement.Tag Property

可以使用Tag属性。它的类型为object,可以设置为任何值。

答案 6 :(得分:0)

我认为 UIElement.Uid 应该有效。在 XAML 中分配它并在代码中访问它。

<Label Uid="FirstName"/>

OR 在样式属性中

<Setter Property="Uid" Value="SecondName"/>

然后在C#代码中引用:


    if (Keyboard.FocusedElement is UIElement uiElement)
    {
        Debug.WriteLine(this, $"{uiElement.Uid}");
    }