Entwickler-Ecke
WinForms - [Newbie][3.5] Listbox "hidden value"?
dolly - Do 19.03.09 15:00
Titel: [Newbie][3.5] Listbox "hidden value"?
Hallo zusammen,
versuche gerade mich in C# (speziell Windows Forms) einzuarbeiten, daher bitte ich schonmal von vorne herein um Verzeihung, falls dieses Thema woanders bereits abgehandelt wurde - ich habe gesucht, hier im Forum und auch ueber Suchmaschinen.
Hier das Problem:
Ich lese einen Registry Key aus (HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall). Die Unterelemente sind GUIDs (also {A1B2C3xxxxx...}). Diese GUID Keys haben wiederum Key Value Tuple wie z.B. "DisplayName" und "UninstallString".
Wenn ich nun den ersten Teil dieser Tuples in die Listbox ausgebe (also DisplayName, heisst in der Liste stehen alle Applikationen, die auf dem System installiert sind), kann ich nicht zu dem anderen Teil des Tuples (UninstallString) aufloesen, weil die Listbox nur den DisplayName speichern kann.
Jetzt koennte ich ueber einen DataTable oder ein Dictionary "DisplayName" zu "UninstallString" aufloesen, das funktioniert aber deshalb nicht, weil z.B. MS Office 2007 SP1 mehrfach in der Liste auftaucht (bzw. verschiedene Keys haben in ihrem Subkey "DisplayName" den String "MS Office 2007 SP1"). DisplayName taugt also nicht als "unique identifier".
In HTML wuerde die Liste schlicht und einfach als hidden value oder einfach ueber <a href=scriptlink?id=ID> eingebunden und somit den Zugang zum Parent Key ermoeglichen. In einer Listbox kann ich das meines Wissens nicht tun...
Hat jemand eine Idee oder Tipp, wie das gemacht werden koennte? Ich habe was von XAML gelesen - ist das die einzige Loesung?
Hier ein bisschen Code dazu, lese Keys aus, speichere die Daten in einem 2-D Rectangular Array und gebe sie dann in einer Listbox aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
| using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.Win32;
namespace GetStarted { class RegistryHandler { public String hostname; public RegistryKey rk; public String[,] regDataTuples; public ArrayList validEntries; public int validEntryCount; public String[] DisplayName;
public RegistryHandler(String hostname) { this.hostname = hostname; }
public bool checkHostname() { try { this.rk = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, this.hostname); return true; } catch { return false; } }
public void getResults() { if (this.rk != null) this.rk = rk.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"); String[] regValues = this.rk.GetSubKeyNames(); validEntryCount = 0; ArrayList validEntries = new ArrayList(); foreach (String s in regValues) { RegistryKey temprk = this.rk.OpenSubKey(s); if (temprk.GetValue("DisplayName") != null && temprk.GetValue("UninstallString") != null && (String)temprk.GetValue("DisplayName") != "" && (String)temprk.GetValue("UninstallString") != "") { validEntryCount++; validEntries.Add(s); } }
this.regDataTuples = new String[2,validEntryCount]; this.DisplayName = new String[validEntryCount]; int i = 0; foreach (String s in validEntries) { RegistryKey temprk = this.rk.OpenSubKey(s); this.DisplayName[i] = temprk.GetValue("DisplayName").ToString(); this.regDataTuples[0,i]=temprk.GetValue("DisplayName").ToString(); this.regDataTuples[1,i]=temprk.GetValue("UninstallString").ToString(); i++; } Array.Sort(this.DisplayName); } } } |
aufgerufen wird von der Windows Forms Applikation aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| public void populateList() { listBox1.Items.Clear(); if (this.hostname_entry_textbox.Text == "") { this.listBox1.Items.Add("no hostname entered"); } else { RegistryHandler rh = new RegistryHandler(this.hostname_entry_textbox.Text); if (rh.checkHostname()) { this.hostname_entry_textbox.Clear(); rh.getResults(); for (int i = 0; i < rh.validEntryCount; i++) { this.listBox1.Items.Add(rh.DisplayName[i]); } } else { this.listBox1.Items.Add("unable to connect to host"); } }
} |
Bitte die Code Qualitaet zu entschuldigen, das war erstmal quick&dirty und wird aufgeraeumt, wenns einmal laeuft ;-)
Kha - Do 19.03.09 15:19
:welcome:
dolly hat folgendes geschrieben : |
| DisplayName taugt also nicht als "unique identifier". |
Ganz genau. Also reicht es nicht, der ListBox nur diese Property mitzugeben, es muss schon das gesamte Tupel sein. Ein passenderer Datentyp als zwei Arrays wäre dafür eine
List<KeyValuePair<string, string>>. Eine solche sollte deine RegistryHandler.GetValues-Methode zurückgeben - und, schwupps, brauchst du in RegistryHandler überhaupt kein hässliches öffentliches Feld mehr :D .
Diese Liste weist du dann ListBox.DataSource zu. Jetzt musst du nur noch der ListBox über DisplayMember="Key" und ValueMember="Value" sagen, welchen Teil vom Tupel sie anzeigen bzw. bei SelectedValue zurückgeben soll.
dolly hat folgendes geschrieben : |
| Ich habe was von XAML gelesen - ist das die einzige Loesung? |
WPF macht einiges eleganter, dafür lernt man es leider nicht an einem Wochenende ;) .
dolly - Do 19.03.09 15:56
Dankeschoen! Probier ich gleich mal aus..
Ich dachte Listbox koennte nur String values annehmen, da lag ich dann wohl grundlegend falsch!
dolly - Fr 20.03.09 14:04
Ok das funktioniert in der Tat, danke!
Wie bringe ich der Liste jetzt bei, das anders zu formatieren. Denn so zeigt die Liste natuerlich die Key Value Pairs, also e.g.
[Adobe Flash Player 10 Active X, C:\Windows\system32\Macromed\Flash\uninstall_activeX.exe]
Mir waere lieber, wenn nur "Adobe Flash Player 10 Active X" angezeigt wuerde ;) Gibt es da eine Moeglichkeit?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| public void populateList() { listBox1.DataSource=null; if (this.hostname_entry_textbox.Text == "") { this.listBox1.Items.Add("no hostname entered"); } else { RegistryHandler rh = new RegistryHandler(this.hostname_entry_textbox.Text); if (rh.checkHostname()) { this.hostname_entry_textbox.Clear(); this.listBox1.DataSource=rh.getResults(); } else { this.listBox1.Items.Add("unable to connect to host"); } }
} |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| public List<KeyValuePair<String, String>> getResults() { if (this.rk != null) { this.rk = rk.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"); String[] regValues = this.rk.GetSubKeyNames(); List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); foreach (String s in regValues) { RegistryKey temprk = this.rk.OpenSubKey(s); if (temprk.GetValue("DisplayName") != null && temprk.GetValue("UninstallString") != null && (String)temprk.GetValue("DisplayName") != "" && (String)temprk.GetValue("UninstallString") != "") { list.Add(new KeyValuePair<string, string>(temprk.GetValue("DisplayName").ToString(), temprk.GetValue("UninstallString").ToString())); } } return list; } else return null; } |
Th69 - Fr 20.03.09 14:34
Das hatte Kha doch schon geschrieben:
| Zitat: |
Jetzt musst du nur noch der ListBox über DisplayMember="Key" und ValueMember="Value" sagen, welchen Teil vom Tupel sie anzeigen bzw. bei SelectedValue zurückgeben soll.
|
dolly - Fr 20.03.09 14:49
whoops, sorry!!
und Problem geloest, vielen Dank!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!