Entwickler-Ecke

WPF / Silverlight - Combobox, Binding, String-Liste


Delete - Di 01.06.10 14:39
Titel: Combobox, Binding, String-Liste
Ich benötige doch noch mal ein bisschen Hilfe. Ich habe ein sehr simples Suche-Pad für SharpDevelop, das eigentlich nur aus einer Textbox und einem Button besteht.
Ich würde gern auf eine Combobox umrüsten, die die bereits eingetippten Begriffe noch mal enthält.
Gibt es da auch eine XAML/WPF-Binding-Lösung? Eine List<string> kann man vermutlich nicht einfach so binden, oder?

Sorry für die dumme Frage, aber ich habe um WPF bisher immer einen Bogen gemacht. :(


Kha - Di 01.06.10 21:02

user profile iconMathiasSimmack hat folgendes geschrieben Zum zitierten Posting springen:
Eine List<string> kann man vermutlich nicht einfach so binden, oder?
Oh doch ;) . Im einfachsten Fall war's das wirklich - ItemsSource will ein IEnumerable, umd die Strings kümmern sich dann ContentPresenter, die dafür automatisch einen TextBlock erstellen.


Christian S. - Di 01.06.10 22:00

Wobei eine List<String> ja kein CollectionChanged-Ereignis feuert, daher wäre vielleicht eine ObservableCollection<String> besser? :-)


Kha - Di 01.06.10 22:49

Wenn ich nochmal drüber nachdenke :gruebel: ... macht durchaus Sinn :D .


Delete - Mi 02.06.10 18:18

Dann werde ich mir mal so eine observierbare Kollektion angucken.
Sorry, ich komme mir gerade wie einer vor, der sich seine Hausaufgaben machen lassen will. :(


user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
um die Strings kümmern sich dann ContentPresenter, die dafür automatisch einen TextBlock erstellen.

Muss ich das machen im XAML-Code?


Christian S. - Mi 02.06.10 18:26

Du musst da nix selber machen, nach Setzen der ItemsSource sollte, sofern Du keine ausgefalleneren Wünsche hast, die Darstellung von alleine gehen.


Kha - Mi 02.06.10 18:31

Genau - war nur zur Hintergrundinformation gedacht, wo die "Magie" überhaupt steckt (nämlich in ContentPresenter.DefaultSelector.SelectTemplate).


Delete - Mi 02.06.10 19:33

user profile iconChristian S. hat folgendes geschrieben Zum zitierten Posting springen:
Du musst da nix selber machen, nach Setzen der ItemsSource sollte, sofern Du keine ausgefalleneren Wünsche hast, die Darstellung von alleine gehen.

Was ist mit dem Zuweisen von "DisplayMemberPath" bzw. "SelectedValuePath"? Ich habe eigentlich nur ein Verständnisproblem mit dem Datenbinding. Dank Sebastians Hilfe beim TOC habe ich damals auch gleich das Options-Panel umgebaut, so dass ich per Binding direkt die Hilfekataloge verlinkt habe:

XML-Daten
1:
2:
3:
<ComboBox Name="help3Catalogs"
  ItemsSource="{Binding}" DisplayMemberPath="ShortName" SelectedValuePath="ShortName"
  SelectionChanged="Help3CatalogsSelectionChanged" />

Hier zeigen "DisplayMemberPath" und "SelectedValuePath" auf ShortName, eine String-Eigenschaft des jeweiligen Hilfekataloges. Das ließ sich bequem ermitteln:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
void Help3CatalogsSelectionChanged(object sender, SelectionChangedEventArgs e)
{
  string item = (string)help3Catalogs.SelectedValue;
  if (!string.IsNullOrEmpty(item)) {
    Help3Service.ActiveCatalogId = item;
  }
}

Aber das war eben eine eigene Klasse, bei der ich auch (rein verständnistechnisch) den Pfad vom Klassennamen zur Eigenschaft nachvollziehen konnte. Aber bei einer ObservableCollection<string> habe ich doch so was nicht. Oder? :nixweiss:


Wie gesagt, sorry für die dummen Fragen.


Kha - Mi 02.06.10 20:50

Auch wenn ich am Anfang die ObservableCollection verplant habe, darfst du uns langsam ruhig glauben, dass das Setzen von ItemsSource genügt :schmoll: . Ohne Pfad zu einer Eigenschaft wird das Objekt selbst gebunden - vergleiche {Binding} vs. {Binding SomeProp} :) .

Edit: Und um gleich noch die DataTemplates ins Spiel zu bringen: DisplayMemberPath="SomeProp" ist die Kurzform von

XML-Daten
1:
2:
3:
4:
5:
<ComboBox.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding ...}" />
    </DataTemplate>
</ComboBox.ItemTemplate>


Delete - Do 03.06.10 06:25

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Auch wenn ich am Anfang die ObservableCollection verplant habe, darfst du uns langsam ruhig glauben, dass das Setzen von ItemsSource genügt :schmoll:

:flehan: Ich glaub's ja. Du weißt doch, dass ich keine Ahnung (mehr) von dem Thema habe. Ich muss mich erst mal wieder damit beschäftigen. :les:


Delete - Do 03.06.10 20:04

Ich hab's jetzt so:

XML-Daten
1:
<ComboBox Name="searchCB" Margin="5,1,5,5" Padding="1" IsEnabled="False" IsEditable="True" PreviewKeyUp="SearchCBPreviewKeyUp" />                    


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
ObservableCollection<string> searchTerms = new ObservableCollection<string>();

void SearchCBPreviewKeyUp(object sender, KeyEventArgs e)
{
  doSearch.IsEnabled = (Help3Environment.IsHelp3ProtocolRegistered && !string.IsNullOrEmpty(searchCB.Text));

  if (e.Key == Key.Return || e.Key == Key.Enter)
    DoSearchClicked(nullnull);
}

void DoSearchClicked(object sender, RoutedEventArgs e)
{
  string term = searchCB.Text;
  if (string.IsNullOrEmpty(term)) {
    throw new ArgumentNullException("term");
  }
  if (searchTerms.IndexOf(term) < 0) searchTerms.Add(term);
  DisplayHelp.Search(term);
}

"doSearch" ist der Button, der nur aktiv ist, wenn a) das Hilfesystem vorhanden ist, und b) wenn was eingetippt wurde.

Dank automatischer Vervollständigung schlägt die Box auch schon mal Sachen vor, selbst wenn man Groß- und Kleinschreibung mischt. Insofern scheint das bloße Prüfen mit "IndexOf" wohl auszureichen?! Aber dennoch die Frage: gibt es Verbesserungspotential? Ich möchte auch keine fertige Lösung! So ein paar kleine Denkanstöße reichen, damit ich was zum Knobeln habe. :)


Kha - Sa 05.06.10 00:35

Dazu fällt mir höchstens noch ein, dass Suchterme bei wiederholter Suche wieder nach oben geschubst werden könnten - MRU eben :) .


Delete - Sa 05.06.10 17:02

Danke. Habe ich eingebaut, aber noch nicht eingecheckt. ;)