2012-04-03 32 views
6

para el registro de las acciones del usuario en mis formas de WPF, he añadido algunos controladores de eventos globales¿Hay algún identificador único para wpf UIElement?

Quiero registrar exactamente lo que el control de incendios caso, ¿hay algún identificador único para un WPF UIElement como ClientId en ASP.Net?

+1

¿Ha probado la propiedad [FrameworkElement.Name] (http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.name.aspx)? – DmitryG

+0

Sí, pero el nombre puede estar vacío, no quiero poner Nombre en cada control exclusivamente para fines de registro –

+0

@ArsenMkrt, el [PersistId] (http://msdn.microsoft.com/en-us/library/ la propiedad system.windows.uielement.persistid.aspx) parece ser lo que estás buscando. Por desgracia, ahora está obsoleto y aparentemente no tiene reemplazo. Tal vez pueda recurrir a la generación de identificadores únicos, en ese caso, consulte [esta pregunta] (http://stackoverflow.com/q/750947/464709). –

Respuesta

2

Parece que encontré la respuesta a mi pregunta, la respuesta es No, ahora forma de hacerlo, como se indica en MSDN aquí (http://msdn.microsoft.com/en-us/magazine/dd483216.aspx)

Observe que la definición de control de ventana de nivel superior no contiene un atributo de nombre . Esto es importante porque, como veremos en breve, cuando escribe automatización de prueba, una forma fácil de obtener una referencia a un control utilizando la biblioteca MUIA es acceder a la propiedad AutomationId, que es generada por el compilador del atributo de Nombre del control. Los controles sin un atributo de nombre XAML no recibirán una propiedad AutomationId. Esta idea es un ejemplo específico de bajo nivel de , la importancia de considerar los problemas de diseño de aplicaciones para las cosas tales como seguridad, extensibilidad y automatización de prueba.

0

No eres más que mirar la adición de un Name o x:Name para que el Window/UserControl/Page expone el control al resto de la clase con el nombre especificado.

<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. 
    } 
} 

Además, siempre se puede utilizar el objeto FrameworkElement.Tag. Está destinado a almacenar información arbitraria, por lo que puede usar esto como un identificador único si así lo desea.

+0

gracias por responder @my, pero el nombre no es lo que estoy buscando, al principio no quiero dar nombre a todos los controles de la interfaz de usuario para el registro, y en segundo lugar, puede ser imposible para una cuadrícula con muchos controles de edición en plantillas de celda ... –

8

¿Por qué no utiliza el código hash?

Puede comparar los valores para asegurarse de que son el mismo objeto, y es fácil de conseguir con .GetHashCode()


Editar

Obviamente esto es diferente cada vez que se ejecuta el programa, por lo en realidad, esta es una mala idea, a menos que desee actualizar el registro cada vez que se registra el proceso. Todavía es posible aunque

quiero decir que podría almacenar un valor hash para cada objeto en el momento en que se crea el registro, pero que no sé si me gusta que

+0

He probado y el problema es que GetHashCode() es solo para esa sesión. Si cierra la aplicación y reinicia los elementos de la interfaz de usuario obtendrán nuevos HashCodes. Pero aún +1. – Paparazzi

+0

@ExitMusic, GetHashCode se cambiará al menos después de reiniciar la aplicación, lo que hará que el registro no se pueda usar ... Quiero tener un identificador más estable –

+0

Los hashes no son únicos. –

0

creo, para el registro de las acciones del usuario, puede usar la propiedad UIAutomation tree y AutomationElement.AutomationId, ya que este enfoque es compatible con todos los controles UI estándar de forma predeterminada. Muchos controles de terceros también son compatibles con AutomationId para sus elementos (por ejemplo, celdas de cuadrícula). Un AutomationId es útil para crear scripts de automatización de prueba.

+0

Hmmmm ... parece que AutomationId también debe configurarse, y si no está configurado, devuelve el nombre que está vacío en nuestro caso ... Supongo que no hay manera de hacer lo que estoy buscando ... –

1

Una forma de hacerlo es con un atributo personalizado. Al igual que ...

El UIElement desea iniciar sesión (por ejemplo, control de usuario):

[UserInterfaceID(ID = "{F436E9B3-C2F6-4CF8-8C75-0A2A756F1C74}")] 
public partial class MyUserControl : UserControl 
{ 
    InitializeComponent(); 
    // or whatever... 
} 

Luego hay la costumbre atributo de clase

[System.AttributeUsage(AttributeTargets.Class)] 
public class UserInterfaceIDAttribute : Attribute 
{ 
    public Guid ID { get; set; } 
} 

En su código, puede hacer algo como esto:

MyUserControl control = new MyUserControl(); 
foreach(object att in control.GetCustomAttributes(typeof(UserInterfaceAttribute),false)) 
{ 
    UserInterfaceAttribute uiAtt = (UserInterfaceAttribute)att; 
    Guid theID = uiAtt.ID; 
} 

Porque está etiquetando el control con un atributo en el código, el identificador único nunca cambia, no importa cuántas veces mates/ejecutes la aplicación.

Por supuesto, este es un ejemplo básico que muestra cómo acceder a la ID, pero es probable que desee utilizar algún tipo de Programación Orientada a Aspectos. Hago exactamente este tipo de cosas usando Castle Windsor Interceptors, pero eso está fuera del alcance de esta publicación.

Lo ideal es que accedas a esta ID cuando hay algún tipo de evento que se activa.El uso de interceptores le permite ir a las llamadas al método de captura antes de invocarlas, en donde puede buscar el ID como se muestra arriba y registrar la acción. Como alternativa, puede simplemente usar

this.GetCustomAttributes(...) 

de algún método cuando se activa un evento en el control e incrustar el código de registro allí. Este patrón no es el mejor porque estás rociando preocupaciones transversales por todas partes haciendo que algún tipo de enfoque de Programación Orientada a Aspectos sea mejor ... pero de nuevo estoy divagando y está fuera del alcance de esta publicación ... pero obtienes la idea.

Espero que esto ayude.

+0

¿Por qué necesito una ¿atributo? Puedo establecer todas las propiedades de Nombre de los elementos de mi UI, solo quiero encontrar un camino sin configurar nada, porque es posible en winform –

Cuestiones relacionadas