2012-07-18 5 views
5

Ich aktualisiere derzeit das Tool meines Vorgängers und ich bin auf einem TreeView Problem fest. Seine Software analysierte Daten einmal und zeigte die Ergebnisse in einer TreeView an. Ich änderte das Werkzeug, um Echtzeitdaten zu analysieren und somit erhält der Benutzer Echtzeitergebnisse. Jetzt möchte ich, dass die Knoten der Baumansicht erweitert bleiben, wenn der Benutzer sie erweitert, selbst nach einem Update. Ich weiß, dass dieses Thema mehrmals diskutiert wurde und ich Stunden damit verbrachte, die Antworten zu lesen, aber ich habe nie eine Lösung für mein Problem gefunden.Erstellen, aktualisieren Sie eine WPF TreeView und erinnern Sie sich an erweiterte Knoten ohne XAML

Das grundlegende Problem ist: Es gibt keinen stabilen Baum mehr und derzeit wird der Baum jedes Mal neu erstellt. Ich habe bis jetzt keine Ahnung von Datenbindung oder XAML und wenig Zeit, um die Programmierung in XAML zu lernen. Unten sehen Sie den Code, wie er von meinem Vorgänger erstellt wurde. Ich habe bis jetzt nichts geändert, ich erinnere mich nur alle 2 bis 5 Sekunden an diese Methode.

Gibt es eine (einfache?) Möglichkeit, die Informationen über erweiterte Knoten irgendwo (global?) Zu speichern und nach der Aktualisierung wieder zu erweitern oder muss ich wirklich erst ein tieferes Verständnis von WPF bekommen?

foreach (Analyzer.ALARM_GROUP alarmGroup in alarmGroupList) 
{ 
    //Display Problem Group 
    TreeViewItem groupItem = new TreeViewItem(); 
    List<String> ListAreas = new List<string>(); 
    string areas = ""; 

    //GROUP HEADER 
    //display alarm group which contains more than one alarm 
    if (alarmGroup.AlarmList.Count > 1) 
    { 
     groupItem.Header = Convert.ToString(alarmGroup.AlarmList.Count) + " --- " + alarmGroup.AlarmList[0].EventTime + "  " + alarmGroup.AlarmList[0].AlarmText + "\n   " 
        + alarmGroup.AlarmList[alarmGroup.AlarmList.Count - 1].EventTime + "  " + alarmGroup.AlarmList[alarmGroup.AlarmList.Count - 1].AlarmText 
        + " --- " + " AREAS: " + areas; 
    } 
    else //display alarm group with only one alarm message 
    { 
     groupItem.Header = Convert.ToString(alarmGroup.AlarmList.Count) + " --- " + alarmGroup.AlarmList[0].EventTime + "  " + alarmGroup.AlarmList[0].AlarmText + " --- " + " AREA: " + areas; 
    } 

    //HEADLINE of single Alarm Item 
    TreeViewItem alarmItem = new TreeViewItem(); 
    alarmItem.Header = "[EVENTTIME]       [ALARMTAG] --- [OPCCONDITION] --- [SEVERITY] --- [AREA] --- [ALARMTEXT]"; 
    alarmItem.FontWeight = FontWeights.SemiBold; 
    groupItem.Items.Add(alarmItem); 

    //Display single alarm messages 
    foreach (var alarm in alarmGroup.AlarmList) 
    { 
     alarmItem = new TreeViewItem(); 
     alarmItem.Header = alarm.EventTime + " --- " + alarm.AlarmTag + " --- " + alarm.Condition + " --- " + alarm.Severity + " --- " + alarm.Area + " --- " + alarm.AlarmText; 
     alarmItem.FontWeight = FontWeights.Normal; 
     groupItem.Items.Add(alarmItem); 
    } 

    AlarmPresentationBox.Items.Add(groupItem); 

Antwort

3

muss ich bekommen ein tieferes Verständnis der WPF wirklich zuerst?

Ich würde sagen Ja, speziell, wenn Sie planen, diese Anwendung für längere Zeit zu arbeiten/zu unterstützen; Und wenn Sie in Zukunft in WPF arbeiten möchten, ist es besser, sich mit XAML- und WPF-Konzepten die Hände schmutzig zu machen.

Persönlich würde ich nie, dass dieses Werkzeug auf diese Weise implementieren, stattdessen würde ich für MVVM approch gehen, wie in folgendem Artikel beschrieben und machen es sauber, wartbar und effizient - Simplifying the WPF TreeView by Using the ViewModel Pattern

Gibt es eine (leicht?) Weg, um die Informationen zu erweiterten Knoten überall zu speichern (? global) und erneut erweitern es nach Refresh

Sie können so etwas wie dies versuchen -

Erstellen Sie eine Liste der Header zu speichern (oder eine einzigartige Eigenschaft/id) aus expandiertem Knoten

private List<string> expandedNodes = new List<string>(); 

Behandeln Sie das Auf- und Zuklappen Ereignis jedes Knotens (mit untergeordneten Knoten)

TreeViewItem alarmItem = new TreeViewItem(); 
alarmItem.Expanded += OnAlarmItemExpanded; 

Aktualisieren der Liste, wenn Knoten erweitert wird/kollabiert -

private void OnAlarmItemExpanded(object sender, RoutedEventArgs e) 
{ 
    TreeViewItem treeNode = sender as TreeViewItem; 
    string header = treeNode.Header.ToString(); 
    if (expandedNodes.Contains(header) == false) 
    { 
     expandedNodes.Add(header); 
    } 
} 

private void OnAlarmItemCollapsed(object sender, RoutedEventArgs e) 
{ 
    TreeViewItem treeNode = sender as TreeViewItem; 
    string header = treeNode.Header.ToString(); 
    if (expandedNodes.Contains(header)) 
    { 
     expandedNodes.Remove(header); 
    } 
} 

das nächste Mal, wenn Sie eine TreeViewItem schaffen, es erweitern, wenn es Header (Uniques Id) wird in Liste -

if (expandedNodes.Contains(header)) 
{ 
    alarmItem.IsExpanded = true; 
} 

Dies muss sowohl für groupItem als auch für alarmItem erfolgen.

+0

Thank you very much.Ich habe gerade einen anderen Ansatz versucht, indem ich den kompletten Tree angehängt habe und die Knoten und ihren Status in einem Wörterbuch gespeichert habe, aber es hat nicht funktioniert. Dein Ansatz klingt besser. Ich implementiere es nur. – Larimow

+0

Vielen Dank noch mehr. Es funktioniert perfekt. Ich hätte diese Frage 3 Tage vorher stellen sollen ... Über WPF: Es gibt zwei andere Probleme, mit denen man sich im Moment befassen muss. Wenn ich diese Probleme löste, könnte ich "meine Hände schmutzig machen". Für jetzt versuche ich XAML – Larimow

+0

gute Lösung zu vermeiden. Aber ich sollte lieber GetHashCode verwenden. Header-String ist nicht sehr eindeutige ID. – shj

-1

CompareTreeViewItem -

private void CompareTreeViewItem(TreeViewItem TViewItem1,TreeViewItemTViewItem2) 
{ 
    if ((string)TViewItem1.Header == (string)TViewItem2.Header) 
    { 
     TViewItem2.IsExpanded = TViewItem1.IsExpanded; 

     if (TViewItem1.Items.Count > 0) 
     { 
      for (int i = 0; i < TViewItem1.Items.Count && i < TViewItem2.Items.Count; i++) 
      { 
       CompareTreeViewItem((TreeViewItem)TViewItem1.Items[i], 
            (TreeViewItem)TViewItem2.Items[i]); 
      } 
     } 
    } 
} 
Verwandte Themen