2008-08-11 5 views
7

Wie instrumentieren Sie Ihre Benutzeroberflächen? In der Vergangenheit habe ich gelesen, dass Leute ihre Benutzeroberflächen instrumentiert haben, aber was ich nicht gefunden habe, sind Beispiele oder Tipps zu wie, um eine UI zu instrumentieren.Eine UI instrumentieren

Mit Instrumentierung meine ich das Sammeln von Daten bezüglich der Nutzung und Leistung des Systems. Ein MSDN-Artikel zur Instrumentierung lautet http://msdn.microsoft.com/en-us/library/x5952w0c.aspx. Ich möchte erfassen, auf welche Schaltflächen die Benutzer klicken, welche Tastaturkürzel sie verwenden, welche Begriffe sie verwenden usw.

  • Wie instrumentieren Sie Ihre Benutzeroberfläche?
  • In welchem ​​Format speichern Sie die Instrumente?
  • Wie verarbeiten Sie die instrumentierten Daten?
  • Wie halten Sie Ihren UI-Code sauber mit dieser Instrumentierungslogik?
  • Im Speziellen implementiere ich meine UI in WPF, so dass dies zusätzliche Herausforderungen im Vergleich zur Instrumentierung einer webbasierten Anwendung bietet. (d. h. müssen die instrumentierten Daten zurück zu einem zentralen Ort usw. übertragen werden). Das heißt, ich denke, dass die Technologie eine einfachere Implementierung der Instrumentierung über Konzepte wie angefügte Eigenschaften bereitstellen kann.

    • Haben Sie eine WPF-Anwendung instrumentiert? Haben Sie Tipps, wie dies erreicht werden kann?

    Edit: Die folgenden Blog-Post stellt eine interessante Lösung: Pixel-In-Gene Blog: Techniques for UI Auditing on WPF apps

    Antwort

    2

    Der folgende Blogpost gibt einige gute Ideen zum Instrumentieren einer WPF-Anwendung: Techniques for UI Auditing on WPF apps.

    +0

    EventManager.RegisterClassHandler hat wirklich den Trick, wenn ich für Tastenklicks, Listenauswahl usw. Sehr wenig Code benötigt wird, Protokollierung einige Interaktion zu tun, die für die gesamte GUI auf die notwendigen Ereignisse zum einhängen. – angularsen

    +0

    Ich wollte nur einen Link zur Verfügung stellen, der für mich funktionierte: http://blog.pixelingene.com/2008/08/techniques-for-ui-auditing-on-wpf-apps/ –

    -1

    Ich habe noch nicht WPF entwickelt mit .. Aber ich würde davon ausgehen, dass es das gleiche wie die meisten anderen Anwendungen, die Sie wollen um den UI-Code so hell wie möglich zu halten. Eine Anzahl von Entwurfsmustern kann dabei verwendet werden, wie zum Beispiel die offensichtlichen MVC und Façade. Ich persönlich versuche immer, die Objekte zwischen den UI- und BL-Ebenen so leicht wie möglich zu halten und sie, wenn möglich, auf Primitiven zu beschränken.

    Dies dann mich auf die Verbesserung der UI-Ebene, ohne die Belange der etwas los zu konzentrieren hilft, wenn ich wieder meine (primitive) Daten werfen ..

    Ich hoffe, dass ich Ihre Frage richtig verstanden habe, und leider kann ich nicht bieten mehr Kontextuelle Hilfe mit WPF.

    2

    Sie könnten log4net betrachten. Es ist ein robustes Protokollierungsframework, das in einer einzelnen DLL vorhanden ist. Es wird auch in einem "nicht anspruchsvollen" Typ-Modus durchgeführt, so dass, wenn ein kritischer Prozess stattfindet, er nicht protokolliert wird, bis Ressourcen ein wenig mehr freigegeben werden.

    Sie könnten einfach eine Reihe von INFO-Level-Loggern einrichten und alle Benutzerinteraktionen nachverfolgen, die Sie benötigen, und es würde keinen Fehler verursachen, die Datei an sich selbst zu senden. Sie könnten dann auch Ihren gesamten FEHLER- und FATAL-Code protokollieren, um eine Datei zu trennen, die Sie einfach zur Bearbeitung an Sie senden können.

    2

    Wenn Sie WPF-Befehle verwenden, kann jeder benutzerdefinierte Befehl dann die Aktion protokolliert protokollieren. Sie können auch protokollieren, wie der Befehl initiiert wurde.

    0

    Vielleicht kann die Microsoft UI Automation für WPF helfen? Es ist ein Framework für die Automatisierung Ihrer Benutzeroberfläche, vielleicht kann es verwendet werden, um Zeug für Sie zu protokollieren ...

    Wir verwenden das Automation Framework zum automatischen Testen unserer Benutzeroberfläche in WPF.

    0

    Haftungsausschluss: Ich arbeite für das Unternehmen, das dieses Produkt verkauft, nicht nur das, aber ich bin ein Entwickler für dieses spezielle Produkt :).

    Wenn Sie an einem kommerziellen Produkt interessiert sind, dann bietet Runtime Intelligence (ein funktionales Add-on für Dotfuscator), das Nutzungsverfolgungsfunktionen in Ihre .NET-Anwendungen einfügt. Wir bieten nicht nur die eigentliche Implementierung der Tracking-Funktionalität, sondern auch die Datensammel-, Verarbeitungs- und Berichtsfunktionen.

    Es gab vor kurzem eine Diskussion über das Business of Software Forum zu diesem Thema, das ich auch hier veröffentlicht: http://discuss.joelonsoftware.com/default.asp?biz.5.680205.26.

    Für einen Überblick über unsere Sachen auf hohem Niveau siehe hier: http://www.preemptive.com/runtime-intelligence-services.html.

    Darüber hinaus arbeite ich gerade an der Ausarbeitung einiger technisch ausgerichteter Dokumentation, da wir feststellen, dass dies ein Bereich ist, den wir definitiv verbessern könnten. Bitte lassen Sie mich wissen, ob jemand Interesse hat, benachrichtigt zu werden.

    3

    Hier ist ein Beispiel, wie ich einen einfachen Ereignis-Manager zum Anhängen an die UI-Ereignisse und Extrahieren von Schlüsselinformationen der Ereignisse, wie Name und Typ des UI-Elements, Name des Ereignisses und den Typnamen des übergeordneten Fensters verwenden. Für Listen extrahiere ich auch den ausgewählten Artikel.

    Diese Lösung lauscht nur auf Klicks von Steuerelementen abgeleitet von ButtonBase (Button, ToggleButton, ...) und Auswahländerungen in Steuerelementen abgeleitet von Selector (ListBox, TabControl, ...). Es sollte einfach sein, sie auf andere Arten von UI-Elementen zu erweitern oder eine feinkörnigere Lösung zu erreichen. Die Lösung ist inspiriert von Brad Leach's answer.

    public class UserInteractionEventsManager 
    { 
        public delegate void ButtonClickedHandler(DateTime time, string eventName, string senderName, string senderTypeName, string parentWindowName); 
        public delegate void SelectorSelectedHandler(DateTime time, string eventName, string senderName, string senderTypeName, string parentWindowName, object selectedObject); 
    
        public event ButtonClickedHandler ButtonClicked; 
        public event SelectorSelectedHandler SelectorSelected; 
    
        public UserInteractionEventsManager() 
        { 
         EventManager.RegisterClassHandler(typeof(ButtonBase), ButtonBase.ClickEvent, new RoutedEventHandler(HandleButtonClicked)); 
         EventManager.RegisterClassHandler(typeof(Selector), Selector.SelectionChangedEvent, new RoutedEventHandler(HandleSelectorSelected)); 
        } 
    
        #region Handling events 
    
        private void HandleSelectorSelected(object sender, RoutedEventArgs e) 
        { 
         // Avoid multiple events due to bubbling. Example: A ListBox inside a TabControl will cause both to send the SelectionChangedEvent. 
         if (sender != e.OriginalSource) return; 
    
         var args = e as SelectionChangedEventArgs; 
         if (args == null || args.AddedItems.Count == 0) return; 
    
         var element = sender as FrameworkElement; 
         if (element == null) return; 
    
         string senderName = GetSenderName(element); 
         string parentWindowName = GetParentWindowTypeName(sender); 
         DateTime time = DateTime.Now; 
         string eventName = e.RoutedEvent.Name; 
         string senderTypeName = sender.GetType().Name; 
         string selectedItemText = args.AddedItems.Count > 0 ? args.AddedItems[0].ToString() : "<no selected items>"; 
    
         if (SelectorSelected != null) 
          SelectorSelected(time, eventName, senderName, senderTypeName, parentWindowName, selectedItemText); 
        } 
    
        private void HandleButtonClicked(object sender, RoutedEventArgs e) 
        { 
         var element = sender as FrameworkElement; 
         if (element == null) return; 
    
         string parentWindowName = GetParentWindowTypeName(sender); 
         DateTime time = DateTime.Now; 
         string eventName = e.RoutedEvent.Name; 
         string senderTypeName = sender.GetType().Name; 
         string senderName = GetSenderName(element); 
    
         if (ButtonClicked != null) 
          ButtonClicked(time, eventName, senderName, senderTypeName, parentWindowName); 
        } 
    
        #endregion 
    
        #region Private helpers 
    
        private static string GetSenderName(FrameworkElement element) 
        { 
         return !String.IsNullOrEmpty(element.Name) ? element.Name : "<no item name>"; 
        } 
    
    
        private static string GetParentWindowTypeName(object sender) 
        { 
         var parent = FindParent<Window>(sender as DependencyObject); 
         return parent != null ? parent.GetType().Name : "<no parent>"; 
        } 
    
        private static T FindParent<T>(DependencyObject item) where T : class 
        { 
         if (item == null) 
          return default(T); 
    
         if (item is T) 
          return item as T; 
    
         DependencyObject parent = VisualTreeHelper.GetParent(item); 
         if (parent == null) 
          return default(T); 
    
         return FindParent<T>(parent); 
        } 
    
        #endregion 
    } 
    

    Und die eigentliche Protokollierung zu tun, ich benutze log4net und erstellt einen separaten Logger namens ‚Interaktion‘ Interaktion mit dem Benutzer zu protokollieren. Die Klasse 'Log' hier ist einfach meine eigene statische Wrapper für log4net.

    Die Ausgabe würde dann etwa so aussehen und nicht relevante Protokolleinträge auslassen.

     
    04/13 08:38:37.069 INFO  Iact ToggleButton.Click by AnalysisButton in MyMainWindow 
    04/13 08:38:38.493 INFO  Iact ListBox.SelectionChanged by ListView in MyMainWindow. Selected: Andreas Larsen 
    04/13 08:38:44.587 INFO  Iact Button.Click by EditEntryButton in MyMainWindow 
    04/13 08:38:46.068 INFO  Iact Button.Click by OkButton in EditEntryDialog 
    04/13 08:38:47.395 INFO  Iact ToggleButton.Click by ExitButton in MyMainWindow 
    
    Verwandte Themen