Hallo,
ich möchte per Code Einträge in einer ListView auswählen. Leider finde ich nur selectAll() für alles auswählen und SelectedIndex für den ersten zu markierenden Eintrag. Wie wähle ich aber den 2. ,4. und 5. Eintrag aus?
Ein listView.Items[index].Selected = true gibt es unter WPF nicht und listView.SelectedItems gibt nur Werte zurück - man kann selbst keien festlegen?
Was habe ich übersehen?
nordside
Was habe ich übersehen?
Die Dependency Properties, bzw. in dem Sonderfall die Attached Properties.
Im konkreten Fall Selector.IsSelected auf true setzen und schon werden die Items selektiert angezeigt.
Baka wa shinanakya naoranai.
Mein XING Profil.
Hi Talla,
Du kommst über den ItemsContainerGenerator an die ListViewItems ran. Die kannst Du dann auf IsSelected=True setzen:
ListView.SetIsSelected(Lv.ItemContainerGenerator.ContainerFromIndex(i), true);
Florian
www.planet-xaml.net
Ich komme leider mit euren Hinweisen nicht zurecht.
Ich kann mit
listview.SetValue(ListView. ...)
auf Propertys zugreifen - leider finde kein Selector
was aber zu kompilieren geht, ist
ListView.SetIsSelected(
listview.ItemContainerGenerator.ContainerFromIndex(2), true);
Bei der Ausführung wird aber eine WException geworfen
Der Wert darf nicht NULL sein.\r\nParametername: element" -
System.ArgumentNullException
Was mache ich da falsch? - Danke für Tipps
nordside
Im Prinzip ist das ja nicht viel anders.
SetIsSelected erbt die ListView ja von Selector und die Funktion macht nichts anderes als auch wie ich, nämlich einfach das IsSelected Property für das DependencyObject das übergeben wird, zu setzen.
Dein Code hat den Vorteil dass man das ListViewItem wo der Content drin ist, nicht explizit kennen muss, sondern man sich das entsprechende automatisch generierte ListViewItem von der entsprechenden ListView holt und dann dort die Eigenschaft setzt.
Nachteilig ist das ganze aber für den Fall: Ich hab ne Menge von ListViewItems und weiß nicht zu welcher ListView sie gehören(Bsp. Zwei ListViews wo Items per D'n'D hin und her geschoben werden). Dann komm ich mit dem ItemContainerGenerator net weit.
Oki, das war jetzt beim Threadersteller anscheinend nicht der Fall, aber ich halte das direkte Setzen der Properties für universeller da ich keine Informationen über den Parent benötige.
Nur so als Ergänzung 😉
Baka wa shinanakya naoranai.
Mein XING Profil.
Original von nordside
Ich komme leider mit euren Hinweisen nicht zurecht.Ich kann mit
listview.SetValue(ListView. ...)
auf Propertys zugreifen - leider finde kein Selector
nordside
Du musst das Property direkt bei den Items setzen. Also eher
ListViewItem1.SetValue(Selector.IsSelected,true);
Und Selector liegt im System.Windows.Controls.Primitives Namespace, vielleicht fehlt da einfach der Verweis wenn du keinen Selector von Intellisense(darauf würd ich mich eh noch net verlassen, zumindest in der Beta2 vom VS 2008 zeigt Intellisense in XAML lange net alles an was wirklich geht) angeboten bekommst.
Baka wa shinanakya naoranai.
Mein XING Profil.
ArgumentNullException - Was mache ich da falsch?
Wahrscheinlich rufst Du die Methode zum falschen Zeitpunkt auf und die Items sind noch gar nicht vorhanden.
Tipps: mal nen Breakpoint setzen und myListView.Items.Count prüfen. Falls die Items noch nicht vorhanden sind. Je nachdem wann du die Items füllst, würde ich z.B. den Loaded Event vor dem Selektieren abwarten.
Florian
www.planet-xaml.net
Hallo
@talla
du hast in Deinem Beitrag ListViewItem1 geschrieben. Daher gehe ich davon aus, dass man das Objekt nimmt und nicht die statische Klasse. Ich versuchte
listview.Items[0].SetValue(Selector.IsSelected, true);
bekomme aber eine Fehlermeldung
'object' does not contain a definition for 'SetValue' and no extension method 'SetValue' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
Den Namespace System.Windows.Controls.Primitives habe ich aber eingebunden. Verwende ich die Klasse ListViewItem finde ich kein Property Selector oder eine Methode SetIsSelected.
@fkruesch
Bevor ich die Einräge im Quelltext markieren möchte, füge ich diese per
listview.Items.Add("item5");
hinzu. Sie werden auch angezeigt. Nur das markieren funktioniert nicht. Ich habe auch den SelectionMode auf Extended gesetzt.
Bin immer noch ratlos 🙁
nordside
Bevor ich die Einräge im Quelltext markieren möchte, füge ich diese ... hinzu
Das reicht aber nicht. Die Items (Daten-Objekte) sind dann zwar vorhanden, aber noch keine ListViewItems, die selektiert werden können.
Also, wie gesagt, passende Events abwarten:
lv.LayoutUpdated += delegate
{
ListViewItem item1 = (ListViewItem)lv.ItemContainerGenerator.ContainerFromIndex(0);
item1.IsSelected = true;
};
lv.Items.Add(1);
Florian
www.planet-xaml.net
bekomme aber eine Fehlermeldung
Ja, diese Fehlermeldung hat nichts mit WPF zu tun, sondern die gibts schon so lang wies .Net gibt. Deine ItemCollection gibt dir nen Object zurück und kein ListViewItem, du müsstest also einfach auf ListViewItem casten und dann könntest du das so machen wie ich vorgeschlagen hab. Das wird bei dir aber net gehen 🙂
Da du keine ListViewItems explizit in deiner ListView einfügst, sondern ja nur Strings(bei deinem Beispiel), wird dir Items[0] auch nur nen string zurückgeben. Der Trick ist jetzt, dass dieser String intern ja aber trotzdem in ein ListViewItem eingefügt wurde von der ListView, und um dieses Item erstmal zu bekommen müsstest du die Funktion die fkruesch vorgeschlagen hat mit dem ItemContainerGenerator nutzen. Dann würdest du dein ListViewItem bekommen und dort könntest du dann entweder auf meine Art direkt mit SetValue oder wie fkruesch es vorgeschlagen hat mit ListView.SetIsSelected setzen.
Verwende ich die Klasse ListViewItem finde ich kein Property Selector oder eine Methode SetIsSelected.
Selector ist auch kein Property sondern eine Klasse und Selector.IsSelectedProperty ist ein attached Property das benutzt wird um den Selektionsstatus zu speichern. Das ich immer Selector.IsSelected geschrieben hab ist mein Fehler 🙁 Weil das gibts auch, aber das it dann nur nen klassisches Property das das attached Property wrappt, für SetValue brauch man direkt das Attached Property.
Und SetIsSelected ist keine Methode von ListViewItem, sondern von der ListView direkt das sie von Selector vererbt bekommen hat.
Eigentlich gibts ja auch noch ne dritte und wahrscheinlich einfachste Variante wenn man Dependency/Attached Properties nicht so mag:
Wenn du dein ListViewItem hast(wo du des herbekommst findest du oben beschrieben), dann kannst du auch direkt das IsSelected Property von ListView setzen 🙂
Baka wa shinanakya naoranai.
Mein XING Profil.
Ich bin jetzt einigermaßen verwirrt X( - deshalb einmal Schritt für Schritt
lv.Items.Add("item5");
nur Items, aber keine ListViewItems hinzufüge? Aber Add() erwartet als Parameter ein object - damit bekommt die ListView doch nicht mit, was ich einfüge String, ListViewItem, StackPanel, ...
ListViewItem item1 = (ListViewItem)lv.ItemContainerGenerator.ContainerFromIndex(1);
Bei mir liefert das null, obwohl lv.Items.Count den Wert 5 hat. Ich habe versucht die Anweisung erfolgreich nach dem LayoutUpdate-Ereignis, als auch direkt nach dem hinzufügen der Items auszuführen - immer kommt nur null.
Mein Quelltext sieht im Moment so aus:
lv.SelectionMode = SelectionMode.Extended;
lv.LayoutUpdated += delegate
{
ListViewItem item1 = (ListViewItem)lv.ItemContainerGenerator.ContainerFromIndex(0);
item1.IsSelected = true;
};
for(int i=0; i<5; i++)
{
ListViewItem lvi = new ListViewItem();
lvi.Content = "item"+i;
lv.Items.Add(lvi);
}
lv.Focus();
nordside
Die ListViewItems werden automatisch erzeugt und die Items als Content dort reingepackt.
Das hier ist also überflüssig:
ListViewItem lvi = new ListViewItem();
lvi.Content = "item"+i;
Versucht es doch mal so:
lv.ItemContainerGenerator.StatusChanged += delegate
{
if (lv.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated) return;
ListViewItem lvItem = (ListViewItem)lv.ItemContainerGenerator.ContainerFromIndex(0);
lvItem.IsSelected = true;
};
lv.Items.Add(1);
lv.Items.Add(2);
lv.Items.Add(3);
Florian
www.planet-xaml.net
Die gute Nachricht: es funktioniert. Man kann auch das Event LayoutUpdated nutzen.
Durch
if (lv.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
return;
}
wird verhindert, dass mit null-Werten anschließend hantiert wird. Wie wird der Status vom ItemContainerGenerator aber geändert?
Ausserdem wird das LayoutUpdated unabhängig von der Anzahl der Items 4mal ausgeführt. Die ersten beiden male wird die Selektion erfüllt - dann können die Items selektiert werden. Kann man das erklären?
Vielen Dank
nordside
LayoutUpdated war eine schlechte Wahl - der wird jedesmal geworfen, wenn das Layout upgedated wird 🙂 Das passiert z.B. auch bei Resize oder wenn sich die Grösse des Panels ändert etc.
Der Status des ItemContainerGenerator wird von der WPF "Engine" im Hintergrund geändert... Du wirfst in die Items Collection irgendwelche Objekte rein und WPF erzeugt dann die entsprechenden ListViewItems als Container für die Objekte.
Das Ganze wird im Hintergrund etwas verzögert, z.B. damit es nicht bei jedem Items.Add erfolgt sondern in einem Rutsch.
Meistens werden die Items ja über DataBinding der ItemsSource gesetzt.
Florian
www.planet-xaml.net
Super - es funktioniert! Event wird jetzt wirklich nur zweimal ausgelöst. Einmal wenn der Status noch nicht "ContainersGenerated" ist, aber danach mit Erfolg.
Noch einmal vielen Dank für Eure Hilfe talla und Florian
nordside