Laden...

Hashtable <-> Databinding

Erstellt von .unreal vor 17 Jahren Letzter Beitrag vor 17 Jahren 4.844 Views
.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren
Hashtable <-> Databinding

Guten Abend

Ich habe ein kleines Problem. Kurz zur Situation: Mein Programm soll in einem Template alle {{Platzhalter}} erkennen. Im Gui sollen anschlhiessend alle diese Platzhalter in einer Listbox erscheinen. Für jeden Platzhalter kann ein Wert gesetzt werden, und anschliessend wieder als eine neue Datei gespeichert werden.

Die Logik habe ich in einer Klasse namens Template realisiert, das war mit einer Hashtable überhaupt kein Problem. Alle gefundenen Platzhalter werden in einer Hashtable gespeichert, wobei der Key der name des Platzhalters ist, und Value der "richtige" Wert.


	public class Template
	{
		private string _template;
		private string _parsedTemplate;
		private Regex _rgxPlaceholders = new Regex(@"\{\{(?<name>\S+)\}\}");
		private Hashtable _placeholders;

		//....

		public void Replace()
		{
			_parsedTemplate = _rgxPlaceholders.Replace(_template, new MatchEvaluator(ReplacePlaceholder));
		}

		private String ReplacePlaceholder(Match m)
		{
			return _placeholders[m.Groups["name"].Value].ToString();
		}
	}

Wie man im Code sieht, ist es sehr bequem, mittels der Hashtable die Platzhalter mit den gewünschten Texten zu ersetzen. Nur würde ich nun gerne die gefundenen Platzhalter (Keys der Hashtable) in einer Listbox, bzw. den Value der Hashtable in einer Textbox mittels Databinding anzeigen, und dem Benutzer die Möglichkeit zu geben, die Platzhalter zu füllen. Anscheinend geht Databinding nicht mit Hashtables 🙁

Meine Alternative wäre alles z.B. in eine ArrayList zu packen, und zur "Suche" des richtigen Eintrages mit dem IComparer Interface arbeite. Bevor ich zu dieser Alternative greife, würde es mich wunder nehmen, ob es mit einer Hashtable wirklich nicht möglich ist, oder ob ich nur was übersehen habe.

Danke für eure Hilfe & Gruss,
.unreal

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

kannst du nicht an Hashtable.Keys bzw. Hashtable.Values binden?

herbivore

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Hi Herbivore

Diesen Vorschlag habe ich vorhin mit google gefunden, klappt auch nicht:


lbItems.DataSource = _template.Placeholder.Keys;

An unhandled exception of type 'System.Exception' occurred in system.windows.forms.dll

Additional information: Complex DataBinding accepts as a data source either an IList or an IListSource

Ist ja auch logisch. Aber wie realisier ich ein simple DataBinding? Mit Listbox.DataBindings.Add wüsst ich nicht auf was ich binden sollte. Items ist ja readonly...

Grrr, warum hab ich nur mein Buch auf der Arbeit vergessen 😠

.unreal

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Hi Herbivore,
wie hast du das mit dem Keys binden gemeint?

Gruss,
.unreal

1.274 Beiträge seit 2005
vor 17 Jahren

versuchs mal nur so

lbItems.DataSource = _template.Placeholder

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Hi LastGentlemen

Das funktioniert leider nicht, weil Hashtable IList nicht implementiert!

An unhandled exception of type 'System.Exception' occurred in system.windows.forms.dll

Additional information: Complex DataBinding accepts as a data source either an IList or an IListSource

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

ich hatte das schon so gemeint, wie du's verstanden hast. Aber wo ist das Problem, die Keys in ein Array oder eine List<T> zu kopieren und dies zu binden?

herbivore

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Hallo Herbivore

Dieses kleine Projekt muss ich leider in .NET 1.1 entwickeln. List<T> ist ja neu in .NET 2.0. Sorry dass ich das erst jetzt sage 🙁

Gruss,
.unreal

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

deshalb schieb ich "Array oder eine List<T>". 🙂

herbivore

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

ich such gerade verzweifelt das "Dieser Beitrag wurde 1 mal editiert..." 😛

Danke & Gruss,
.unreal

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

🙂

das kannst du bei Moderatoren lange suchen. Egal wie oft Moderatoren eigene oder fremde Beiträge editieren, es wird nie angezeigt. Aber ich schwöre bei allem was mir heilig ist, dass das mit dem Array von Anfang an dastand.

herbivore

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Hi Herbivore

Das war mir schon von Anfang an klar, darum auch diese Antwort 😃

.unreal

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Zurück zum Problem, hatte wieder Zeit mir Gedanken zu machen:

Herbivore, mit deinem Vorschlag könnte ich die Keys/Values binden, allerdings ist der Nutzen relativ klein, da die Methode - wie der Name schon sagt - das Array kopiert und nicht referenziert. Im Model events zu implementieren, damit ich bei Änderungen die beiden Arrays erneut kopieren kann, finde ich nicht sehr sauber. Ich denke da ist eine ArrayList sauberer. Sehr schade, Hashtables können sehr komfortabel sein 🙂 Falls noch jemand eine Idee hätte, wäre ich natürlich immernoch sehr interessiert.

.unreal

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

wenn ich es mir nochmal überlege, sind die möglichen Änderungen ja vermutlich auch der Grund, warum das Binding einer Hashtable nicht funktioniert. Denn wenn über das Control neue Keys eingegeben werden, wo kommen dann die passenden Values her?

Damit will ich aber nicht von "Falls noch jemand eine Idee hätte, wäre ich natürlich immernoch sehr interessiert." ablenken.

herbivore

.unreal Themenstarter:in
563 Beiträge seit 2004
vor 17 Jahren

Original von herbivore
... sind die möglichen Änderungen ja vermutlich auch der Grund, warum das Binding einer Hashtable nicht funktioniert.

Ja, der Index ist nicht irgendein objekt, sondern ein Integer. Schade dass eauch die SortedList kein IList implementiert, die ist auf beide arten ansprechbar. Ich kenne mich da noch zuwenig aus um genau zu verstehen, warum das so ist, wird wohl auch seinen Grund haben.

.unreal

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo .unreal,

sowohl Hashable also auch SortedList arbeiten mit Values und Keys, alle anderen Collections im Prinzip nur mit Values. Entsprechend deklariert IList z.B. eine Add-Methode mit einem Parameter mit Namen value. Der Einfügepunkt ergibt sich automatisch aus der Art der Collection - bei der ArrayList ist er z.B. immer bei Index Count. Hashtable und SortedList haben aber nur eine Add-Methode mit den Parametern key und value und können den Key auch nicht automatisch bestimmen. Deshalb können sie keine Add-Methode implementieren, wie von IList gefordert. Damit können sie aber IList eben gar nicht implementieren.

herbivore

B
26 Beiträge seit 2006
vor 17 Jahren
Hashtablevalue an Button binden

hy.

wuerd gern einen wert an einer bestimmten stelle in einer hashtable an einen button binden. ist das moeglich? die hashtable braucht nicht geaendert zu werden.


bExit.DataBindings.Add(new Binding("Text", Obj, "myHashtable")); //???

funzt nicht.

danke fuer jede Hilfe.

--
ciao baer

B
26 Beiträge seit 2006
vor 17 Jahren

hy.

hat keiner eine idee?

vielleicht zu wenig erklaert?

also: d hashtable hat als key den Namen des Buttons/Labels oder sonstiges... zB bExit. und als Value steht drinnen der String, wie der Text des Buttons heißen soll.

mit nem Array is es net moeglich, da dann die beziehung verloren geht. und selbst bei einem array muesste man den index mitgeben, an welcher stelle der gewuenschte string steht.

ne andere moeglichkeit waere folgendes property in die dll reinzugeben:


private string newLocalizedString;

public string NewLocalizedString
{
	set { getLocalizedString(value); }
	get { return newLocalizedString;}
}

private void getLocalizedString(value)
{
       newLocalizedString = myHashtable[value];
}

wenn nun ein button den neuen text haben will, dann ruft er zuerst SET auf, und danach GET.

das problem ist, dass ne menge buttons usw. ihren text so bekommen, und da koennte es zu problemen kommen...

any ideas?

--
ciao baer

B
26 Beiträge seit 2006
vor 17 Jahren

hy.

bin noch immer nicht draufgekommen wie das funktionieren koennte.

hat vielleicht jemand ein sample fuer komplexes databinding? vielleicht hilft das weiter. (online is nicht viel nuetzliches zu finden)

tia

ps: falls noch jemandem was einfaellt bitte berichten

--
ciao baer

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo baer,

was hindert daran, den Wert erst aus der Hashtable herauszuholen und dann zu binden?

herbvore

B
26 Beiträge seit 2006
vor 17 Jahren

hallo herbivore.

danke fuer deine antwort.

meinst du so wie 2 antworten drueber? zuerst ruf ich die -set propertie auf und dann die get? und daran sind die buttons gebunden?

hab ich probiert. doch happerts anscheinend an nem event. das wird nicht ausgeloest.

das problem ist, dass im endeffekt mehrere buttons/labels usw.alle nacheinander darauf zugreifen. und wenn alle an die gleiche property gebunden werden, dann werden die auch alle gleichzeitig gesetzt, nehme ich mal an (waere irgendwie logisch). auch wenn sie nacheinander aufgerufen werden. vielleicht mal ein bsp wie ichs mir gedacht hab:


// Form:
this.loc.LocalizedString = "bExit";
this.bExit.DataBindings.Add(new Binding("Text", loc, "LocalizedString"));
this.loc.LocalizedString = "lTest0";
this.lTest0.DataBindings.Add(new Binding("Text", loc, "LocalizedString"));

	private void miGerman_Click(object sender, System.EventArgs e)
		{
			loc.CurrentLanguage = "de";
			// MessageBox.Show(loc.CurrentLanguage);
		}

// Localization: (class)

public string LocalizedString
{
get { return localizedString; }
set { localizedString = getLocalizedString(value); }
}


public string CurrentLanguage
		{
			get { return currentLanguage; }
			set
			{
				currentLanguage = value;
				LocalizedStringChanged.Invoke(this, new EventArgs());
			}
		}

ich der Form hab ich 2 MenuItems (hier ist 1 erwaehnt) das die currentLanguage auf ne andere Sprache setzt. und sobald das geschieht sollte das Event ausgeloest werden.

u wenn ich extra properties fuer alle values aus der hashtable mache, dann wird es ziemlich unuebersichtlich.

ich hoffe nun ist es verstaendlicher...

--
ciao baer

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo baer,

meinst du so wie 2 antworten drueber?

nicht zwangsläufig. Das Herausholen per Property wäre nur eine Möglichkeit. Ich meinte eher direkt herausholen also ht ["key"].

Aber unabhängig davon. Du willst ja wohl deine Anwendung lokalisieren. Da gibt es ja Massen von Dokumentation drüber. Vielleicht solltest du erstmal einen Schritt von deinem Lösungsansatz zurücktreten und schauen, welche Möglichkeiten und Anssätze (auch ohne Databinding) es sonst noch gibt.

herbivore

B
26 Beiträge seit 2006
vor 17 Jahren

danke fuer die schnelle antwort.

das lokalisieren an sich funktioniert (verwende die komponente von Golo Haas, habs nur auf .NET 1.1 angepasst - Borland 2006). nur das problem zur zeit ist, dass er die sprache on the fly wechseln soll.

eine moeglichkeit hab ich schon gefunden. die waere:


this.Controls.Clear();
this.Events.Dispose();
this.InitializeComponent();

aber da zeichnet er ja alles neu, und damit gehen die ganzen Werte die schon eingetragen wurden verloren.

--
ciao baer