Laden...

Treeview rekursiv befüllen

Erstellt von flflfl vor 14 Jahren Letzter Beitrag vor 14 Jahren 13.676 Views
F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren
Treeview rekursiv befüllen

Hallo,

in meiner Datenbank stehen viele Kategorien und Unterkategorien (Elemente werden gespeichert mit "Titel", "ID" und "ParentID"), die ich in einer Treeview darstellen will.

Die Unterkategorien können variabel von 1 bis 10 Ebenen tief sein. Da ich also in den Unterkategorien immer unterschiedlich viele Nodes und so wieder Parents habe, habe ich mir gedacht, die Treeview rekursiv zu befüllen. Ich habe dazu aber keine guten Beispiele gefunden.

Bin ich auf den richtigen Weg? Habt ihr ein paar Beispiele / Anregungen für mich?

danke flo

821 Beiträge seit 2009
vor 14 Jahren

Jap, du kannste den TreeView sehr einfach rekursiv befüllen.

Die Frage die du dir stellen muss, ist nur, ob du bei jeder Rekursion wieder eine Datenbankabfrage starten willst.

Wenn du mit WPF arbeites, weißt du deinem Treeview ein HieraricatDataTemplate zu, indem du wiederrum über die Property ItemsSource bestimmst, wo dieser jeweils seine SubElemente herbeziehen soll.

Auf C# - Seite sieht es dann so aus, dass jedes Object ein Collectin-Property hat, welches z.B. Children heißt.
Dieses Collectin-Property steuert über die get-Methode, was geschen soll, wenn die Sub-Elemente angefragt werden.
Hier kannst du beliebigen Code reinschreiben (z.B. auch eine Datenbankabfrage, welche alle Elemente abfragt, welche als ParentId die Id des aktuellen Elementes haben).

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

hallo,

das heißt, wenn einer auf den parent node klickt, mache ich ein event, dass alle childrens aus der datenbank holt und ausließt? wie kann ich dann die childrens genau diesem node zuweißen? bzw. wenn ein parent auch children hat, ist in der treeview ein pfeil vor dem text, um anzuzeigen, dass es eben ein parent ist. wenn ich aber keine childs beim ersten mal zuweise, dann ist der pfeil nicht da und keiner weiß, dass es noch eine ebene hinunter geht...

lg flo

3.430 Beiträge seit 2007
vor 14 Jahren

Hallo flflflf,

am einfachsten ist wenn du einfach eine ObservableCollection<myTreeViewItem> machst und diese dann als ItemSource verwendest.

Die Klasse MyTreeViewItem würde ungefähr so aussehen


public class MyTreeViewItem : INotifyPopertyChanged
{
   public ObservableCollection<MyTreeViewItem> Children{get;set;}
   public string Name {get;set;}
   //Noch weitere Properties
}

Somit hast du eine schöne Struktur.
Natürlich musst du dann noch das hierachichalDataTemplate definieren

Gruss
Michael

821 Beiträge seit 2009
vor 14 Jahren

Also mit Events machst du gar nix.

Das Childrens-Property steuert dir quasi durch seinen Getter, wann es die Elemente brauch.
Wpf ist dabei so inteligen und fordert nur dann das Childrens-Property dazu auf, wenn die Elemente gebraucht werden, sprich spätestens dann, wenn die GUI eine Ebene drüber wissen muss, ob sie einen Pfeil (SubElements vorhanden) zeichnen muss oder nicht.

Hier ein verwendbarer Quellcode, der dir sicherlich besser helfen wird als meine Text 😃
Du siehst über die Debug-Ausgabe, wann Childrens im Getter angefordert werden:

GUI


<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1"  xmlns:sd="http://schemas.divelements.co.uk/wpf/sanddock">
    
    <Window.Resources>
        
        <HierarchicalDataTemplate x:Key="DT" ItemsSource="{Binding Childrens}">
            <TextBox Text="{Binding Text}" />
        </HierarchicalDataTemplate>
    </Window.Resources>


  

        
        <TreeView ItemTemplate="{StaticResource DT}" ItemsSource="{Binding Item.Childrens}">
            
        </TreeView>



</Window>

C#


namespace WpfApplication1
{
    /// <summary>
    /// Interaktionslogik für Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {

        public ItemVM Item { get; set; }

        public Window1()
        {
            Item = new ItemVM("root");
            this.DataContext = this;
        }

    }


    public class ItemVM
    {
        public string Text { get; set; }
        public ObservableCollection<ItemVM> Childrens
        {
            get
            {
                ObservableCollection<ItemVM> returnment = new ObservableCollection<ItemVM>();
                for(int i=0; i<10; i++) returnment.Add(new ItemVM("Item Nr. " + i));

                System.Diagnostics.Debug.WriteLine("Getting Subitems");

                return returnment;
            }
        }

        public ItemVM(string text)
        {
            this.Text = text;
        }
    }
}


2.223 Beiträge seit 2005
vor 14 Jahren

Hallo flflfl,

die Richtung von michlG wäre schon der Richtige Weg

und auch wenn der Weg von meisteralex noch nicht ganz richtig ist, bringt Dich auch dieser Beitrag deinem Ziel riesen Schritt näher

Herzliche Grüße
BlackCoin

821 Beiträge seit 2009
vor 14 Jahren

Ich bitte um Erklärung, was du unter "nicht ganz richtig" verstehst g

Also die Datenbankabfrage hab ich natürlich weggelassen.

2.223 Beiträge seit 2005
vor 14 Jahren

Halllo meisteralex,

probiere es auch und du wirst es sehen

Herzliche Grüße
BlackCoin

821 Beiträge seit 2009
vor 14 Jahren

Hab ich, bei mir läuft der code einwandfrei.

2.223 Beiträge seit 2005
vor 14 Jahren

auch in den tieferliegenden Ebenen?

821 Beiträge seit 2009
vor 14 Jahren

Ja bei mir klappt alles einwandfrei, auch wenn ich mich bis ebenentiefe 20 durchklicke.
Wo sind denn deine Bedenken ?

2.223 Beiträge seit 2005
vor 14 Jahren

sorry, ich meinte die erste ebene (root)

das kommt davon wenn ich mich ablenken lasse, die tiefsten ebene sollten bis zu einer bestimmten Tiefe ohne Probleme Funktionieren. (bis auf das nach einer anzahl von 255 Items ende ist aber dafür kannst du nichts)

Herzliche Grüße
BlackCoin

821 Beiträge seit 2009
vor 14 Jahren

Also die erste Ebene klappt bei mir auch einwandfrei.
Nunja villeicht hätte man es eleganter lösen können und statt eines ItemVM Objectes eine Collection von ItemVM Objecten anlegen können und die ItemsSource des TreeViews direkt an die Collection binden können.

Willst du darauf hinaus? Bzw. sag doch einfach was du bemägeln willst, ich will schließlich auch noch was lernen.

2.223 Beiträge seit 2005
vor 14 Jahren

genau das ist es du benutzt an der Untersten Stelle [Root] die klasse nur als Speicher für die Items und die Root ebene Verschwindet dadurch.
Dies ist aber eher nur ein kleinere Unschönheit, die man aufgrund dessen das es als Beispiel gedacht war auch so stehen lassen kann.

ich würde es zwar ein kleines wenig anders machen aber das ist ja Geschmackssache


<HierarchicalDataTemplate DataType="{x:Type local:ItemVM}" ItemsSource="{Binding Childrens}">
            <TextBox Text="{Binding Text}" />
        </HierarchicalDataTemplate>

Herzliche Grüße
BlackCoin

925 Beiträge seit 2004
vor 14 Jahren

Jap, du kannste den TreeView sehr einfach rekursiv befüllen.

Die Frage die du dir stellen muss, ist nur, ob du bei jeder Rekursion wieder eine Datenbankabfrage starten willst.

Wenn du mit WPF arbeites, weißt du deinem Treeview ein HieraricatDataTemplate zu, indem du wiederrum über die Property ItemsSource bestimmst, wo dieser jeweils seine SubElemente herbeziehen soll.

Auf C# - Seite sieht es dann so aus, dass jedes Object ein Collectin-Property hat, welches z.B. Children heißt.
Dieses Collectin-Property steuert über die get-Methode, was geschen soll, wenn die Sub-Elemente angefragt werden.
Hier kannst du beliebigen Code reinschreiben (z.B. auch eine Datenbankabfrage, welche alle Elemente abfragt, welche als ParentId die Id des aktuellen Elementes haben).

OT: ich bin zwar kein Mod, aber bitte achte trotzdem mal darauf, dass du zumindest die Schlüsselbegriffe (Collection, HierarchicalDataTemplate) korrekt schreibst! Das vereinfacht die Suche und führt sonst zu Verwirrung.

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

hallo,

habe gerade das beispiel von meisteralex ausprobiert und bin erstmal beeindruckt 😃

meine frage ist nur noch: wie bekomme ich die daten aus der db (id, parentid, titel) in die ObservableCollection?

danke schon mal für eure super hilfe!
flo

p.s. bitte entschuldigt, aber es ist mein erstes wpf-projekt!

821 Beiträge seit 2009
vor 14 Jahren

Wo genau ist dein Knapppunkt ?

Also als erstes solltest du über eine Methode deiner Wahl eine Datenbankabfrage machen.
Dann verpackst du die Daten, welche du aus der Datenbank bekommen hasta in Objekte von Typ aus denen die ObserverableCollection besteht (in diesem Fall heißt der Datentyp bei mir ItemVM).

Gruß MA

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

hallo,

also wenn ich alles richtig verstehe muss ich das so machen:

ich such mir alle parents

  1. ich übergeb immer eine parent id und ruf damit die itemvm auf.
  2. mit der id such ich mir alle childs und ruf damit wieder die itemvm auf.
  3. mit der child id such ich mir weitere childs usw...

passt das?

danke für deine hilfe!
flo

821 Beiträge seit 2009
vor 14 Jahren

Ja g, dass ist so ungefähr die Definition von Rekursion.

Also ein Objekt der Klasse ItemVM weiß eigentlich immer nur, welche Kinder es hat.
Ganz oben steht sozusagen der root node, welche ich in meinen Datenstrukturen immer dadurch definiere, dass die ParentID des Root-Nodes -1 oder 0 ist.

Diesen Root-Node nimmst du nun und verpackst ihn in ein Objekt der Klasse ItemVM. Hierbei bildest du natürlich alle wichtigen Attribute aus der Datenbank in Attribute der klasse ab.
Der Rest erfolgt durch rekursion undzwar wie folgt:
Sobald von einem Item die Childrens angefordert werden, (der getter der Childrens-Property wird angefordert) stellt das Item wieder eine Datenbankverbindung her um alle Elemente zu suchen, welche gerade dieses Item als Vater haben). Diese angeforderten Elemente werden nun von dem Objekt der Klasse ItemVM wiederrum in Objekte vom Typ ItemVM verpackt und in die Childrens-Collection geschubst.
Das wars, alles andere läuft automatisch.

Wie schon angedeutet, ist diese vorgehensweise nicht immer die optimale Lösung, da für jeden Rutsch von Unterlementen ein neuer Datenbankquery ausgeführt werden muss.
Wenn du keine enge Synchronität zur Datenbank-Basis brauchst kannst du auch so vorgehen, dass du vorab alle Elemente der planen Datenbanktabelle in eine Collection läds, welche außen vor stehst und bei der Betankung deiner Children-Propertys nicht direkt auf die Elemente der DB, sondern auf diese Collection abfragst (z.B. mit linq oder altmodisch itterativ).
Aber dazu weiß ich zu wenig von deiner App um dir da Rat zu geben.

Gruß MA

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

yeah 🙂 ich habs geschafft.

eine frage hab ich noch:
Ich hab das Label so an die TreeView gebunden:

<Label Content="{Binding sTitle}" Tag="{Binding iID}" />

wie kann ich nun den Tag vom Label beim Auswählen des Childs auslesen?

danke flo

821 Beiträge seit 2009
vor 14 Jahren

Warum willst du das tun ?
Wozu benutzt du die Property Tag überhaupt, wusste bis jetzt noch nichtmal das es die gibt g

Nein jetzt mal im Ernst, wozu brauchst du die Information, die du da an das Property Tag gebunden hast ?

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

hi,

naja, einmal der Content des Labels, damit was gescheites angezeigt wird und einmal wird die Id im Tag gespeichert, damit ich den richtigen Datensatz in der Datenbank wieder finde, wenn wer auf das Label klickt...

oder wie macht man das "normal"? wie gesagt, ist meiner erste wpf anwendung...

lg flo

821 Beiträge seit 2009
vor 14 Jahren

Also Identifier in der GUI irgendwie zu speichern und damit Rückschlüsse auf das Element zu ziehen ist sehr sehr unsaubere programmierung.

Das mit dem Labelbinding, wo du die Property an die Content-Eigenschaft bindest ist vollkommen ok und der richtige Weg - soweit so gut.

Wenn du nun mit den Objekten in der Listview arbeites, dann arbeitest du ja mit den Objekten, welche Datensätze aus deiner Datenbank repräsentieren. Du hast so zu sagen deine Datenbankeinträge auf Objekte in einem Objektorientierten Kontext gemappt.
Ab diesem Zeitpunkt solltest du allerdings auch objektorientiert und nicht mehr relational denken, daher brauchst du die Id höchstens erst wieder, wenn du das Objekt zurück in die Datenbank speichern (oder löschen) willst.

Um dir jetzt genauer zu erklären, wie du vorgehen muss, wenn "jemand auf das label" klickt, müsste ich wissen was du vorhast. Generell feuert das Listview ja ein Event, wenn jemand ein Item (in deinme Fall templetisiert durch ein Label) klickt. Du könntest z.B. auf dieses Event, welches das ListView feuert, reagieren, nachsehen, welches Item aktuell selektiert ist und dann mit diesem Objekt weiterarbeiten, um es z.B. in einem DetailView anzuzeigen.
Hierfür bietet dir WPF jedoch auch wesentlich elegantere Methoden.

Kann es sein, dass du aus der prozeduralorientierten Skriptecke kommst ? Ich hab früher selbst viele PHP-Skripte nach der Vorgehensweise geschreiben, wie du sie geschildert hast und in diesem Kontext ist das gar nicht mal so verkehrt.

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

Hi,

erwischt, ich komme aus dem php-bereich 😃

also, das ganze gehört zu ein paar tests für eine backend shopverwaltung. man erstellt den artikel und wählt aus der treeview dann die passende kategorie aus. die kategorie wird dann beim artikel in der datenbank gespeichert (deswegen brauch ich die id wieder).

lg flo

821 Beiträge seit 2009
vor 14 Jahren

Da musst du jetzt Objektorientiert denken.
Der Artikel wird ja auch als Objekt einer Klasse erstellt. Dieses Objekt ist dann über eine Referenz mit einem KategorieObject (des Typs ItemVM, wenn wir beim Beispiel bleiben wollen) assoziert und stellt damit die Verbindung von ArtikelObjekt zu KategorieObjekt her.
Erst beim Zurückspeichern wird wieder von der Objektorientierten Denkweise abgelassen. Hierzu geht man am einfachsten so vor, dass dein Artikel-Objekt eine SaveToDatabase() - Methode hat, welche sich über die Referenz auf das KategorieObject beim Speichern in die Datenbank erst wieder die entsprechenden KategorieID holt.

Wenn du eine sehr prozedurale, relationale Denkweise gewöhnt bist, wird das sicherlich nicht so ganz einfach da umzudenken, in einer Sprache wie C# wirst du jedoch nicht drumrum kommen, dir dieses Denken aneignen zu müssen.
Vor allem musst du , wenn du aus der PHP-Webentwicklung kommst von dem Gedanken ablassen, dass ein Programm eine statischen Zustand hat, wie ein Webseiten-View, sondern eher dazu übergehen ein Programm als ein stetig fließendes Konstrukt zu sehen.

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

aber spätestens beim SaveToDatabase() brauche ich wieder die ID. Wie greife ich denn dann darauf zu?

lg flo

821 Beiträge seit 2009
vor 14 Jahren

die speicherst du dir am anfang in ein private Attribut deines Objektes weg. Beim speichern des Artikel-Objektes wird dann über die Referenz auf das Kategorie-Objekt die KategorieId aus dem KategorieObject ausgelesen

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

die speicherst du dir am anfang in ein private Attribut deines Objektes weg ...also zubeispiel in label.tag?
Beim speichern des Artikel-Objektes wird dann über die Referenz auf das Kategorie-Objekt die KategorieId aus dem KategorieObject ausgelesen

...kannst du mir dazu noch ein kleines beispiel geben?

danke, du hast mir bisher sehr viel geholfen.

lg flo

821 Beiträge seit 2009
vor 14 Jahren

Nein nicht im Label. Dein Label ist nur eine Möglichkeit zur Abbildung eines Attributes eines Objektes.
Sozusagen Mittel zum Zweck um (einen Teil von) ItemVM zu visualisieren.

Beispiel:

Nehemen wir an, du hast eine Klasse Kategorie

public class Kategorie
{
private int databaseId;
List<Kategorie> Children;
public int DatabaseId { get { return databaseId; } }
...
...
...
}

und eine Klasse Artikel, welche die Referenz zu einem Kategorie-Objekt beinhaltet, zu dessen Kategorie es gehört:

public class Artikel
{
private Kategorie isInKategorie;
private string artikelDescription;
private string artikelFullDescription;

public SaveToDatabase()
{
string updateQuery = "Update Artikel Set kategorieid = '" + this.isInKategorie.DatabaseId + "' ....... ";
....
}

....
}

Die Methode SaveToDatabase zeigt dir , wie du an die ID des referenzierten Artikel-Objektes gelangst.

Dies ist aber nur der absolut einfachste weg um eine persistente Datenspeicherung zu realisieren.
Sobald dein Projekt umfangreicher wird, oder Ansprüche an Sicherheit etc. stellt, solltest du dir andere Pattern ansehen.

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

ok, also ich brauch aber doch noch in public class Kategorie ein set, oder wie soll ich die datenbank id sonst setzen?

und die klasse (kategorie) ruf ich dann im public ItemVM(string title) auf, oder?

821 Beiträge seit 2009
vor 14 Jahren

die Datenbank-ID kannst du über verschiedene Wege setzten. Meist macht man es Aber wohl im Konstruktor.

und die klasse (kategorie) ruf ich dann im public ItemVM(string title) auf, oder?

Diese Aussage verstehe ich nicht.

Aber solltest du dir nicht erstmal ein Buch holen und dir die Grundlagen der objektorientierten Programmierung aneignen, bevor du ein Projekt oder ähnliches startest ?

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

hallo,

zuerst mal: sorry für die verspätete antwort - ich war im urlaub

ich habe mir schon ein buch zugelegt, aber ich bräuchte noch ein beispiel zum zugriff auf die treeview.

danke, flo

821 Beiträge seit 2009
vor 14 Jahren

Am besten machst du nen neuen Thread auf oder sprichst mich im ICQ an, sonst wird das hier zu unübersichtlich.

Gruß
MA

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

Ist nicht mehr nötig - ich habs jetzt selber zusammen gebracht! freu

Danke für deine Hilfe!

Eine Frage hätte ich noch: wie kann ich die TreeView so öffnen, dass schon in Child vorausgewählt ist?

Danke, flo

821 Beiträge seit 2009
vor 14 Jahren

"das schon in Child vorausgewählt ist" ... ?

Meinst du die Vorselektion eines Items ? Hierbei müsste dir die Property IsSeleted von TreeViewItem behilflich sein.
Um genaueres zu sagen müsste ich deinen Code sehen.

Gruß MA

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

ja genau. sollte natürlich "das schon ein Child vorausgewählt ist" heißen!

der code:

xaml

<Window.Resources>
        <HierarchicalDataTemplate x:Key="DT" ItemsSource="{Binding Childrens}">
            <Label Content="{Binding sTitle}" Height="24" Margin="0" />
        </HierarchicalDataTemplate>
    </Window.Resources>

<TreeView Grid.Row="0" Grid.RowSpan="3" Height="300" ItemTemplate="{StaticResource DT}" ItemsSource="{Binding Item.Childrens}" Name="treKategorien" MouseDoubleClick="treKategorien_MouseDoubleClick" SelectedItemChanged="treKategorien_SelectedItemChanged" />

c#


        public class ItemVM
        {
            public string sTitle { get; set; }
            public int iId { get; set; }

            public ObservableCollection<ItemVM> Childrens
            {
                get
                {
                    ObservableCollection<ItemVM> returnment = new ObservableCollection<ItemVM>();
                    dbKategories dbKat = new dbKategories();
                    dbKat.dbConnect();
                    DataTable dtKat = new DataTable();
                    if (iId == -1) //Top Parents holen
                    {
                        dtKat = dbKat.dbSelect("SELECT Name, ID FROM Kategorien WHERE ID = ParentID");
                    }
                    else //Childs holen
                    {
                        dtKat = dbKat.dbSelect("SELECT Name, ID FROM Kategorien WHERE ID <> ParentID AND ParentID = " + iId);
                    }

                    for (int i = 0; i < dtKat.Rows.Count; i++)
                    {
                        returnment.Add(new ItemVM(dtKat.Rows[i]["Name"].ToString(), 
                                                  Convert.ToInt32(dtKat.Rows[i]["ID"])));
                    }
                    dbKat.dbDisConnect();

                    return returnment;
                }
            }

            public ItemVM(string sTitle, int iId)
            {
                this.sTitle = sTitle;
                this.iId = iId;
            }
        }

lg flo

821 Beiträge seit 2009
vor 14 Jahren

Jap, also wie gesagt:
Verpasse deinem ItemVM eine Property IsSelected und Binde diese Property über einen Trigger an dein TreeView.
Setzt du die Property IsSelected dann im ViewModel auf true, so ist sie auch im TreeView selektiert.

Gruß MA

F
flflfl Themenstarter:in
21 Beiträge seit 2009
vor 14 Jahren

ok, habe jetzt den code so verändert:

xaml

<TreeView Grid.Row="0" Grid.RowSpan="4" Height="300" ItemTemplate="{StaticResource DT}" ItemsSource="{Binding Item.Childrens}" Name="treKategorien" MouseDoubleClick="treKategorien_MouseDoubleClick" SelectedItemChanged="treKategorien_SelectedItemChanged">
            <DataTrigger Binding="{Binding IsSelected}">
                <Setter Property="TreeViewItem.IsSelected" Value="True"></Setter>
            </DataTrigger>
        </TreeView>

c#

public class ItemVM
        {
            public string sTitle { get; set; }
            public int iId { get; set; }
            public int iPreSelected { get; set; }
            public bool IsSelected { get; set; }

            public ObservableCollection<ItemVM> Childrens
            {
                get
                {
                    ObservableCollection<ItemVM> returnment = new ObservableCollection<ItemVM>();
                    dbKategories dbKat = new dbKategories();
                    dbKat.dbConnect();
                    DataTable dtKat = new DataTable();
                    if (iId == -1) //Top Parents holen
                    {
                        dtKat = dbKat.dbSelect("SELECT CategoryName, CategoryID FROM Kategorien WHERE CategoryID = CategoryParentID");
                    }
                    else //Childs holen
                    {
                        dtKat = dbKat.dbSelect("SELECT CategoryName, CategoryID FROM Kategorien WHERE CategoryID <> CategoryParentID AND CategoryParentID = " + iId);
                    }

                    for (int i = 0; i < dtKat.Rows.Count; i++)
                    {
                        returnment.Add(new ItemVM(dtKat.Rows[i]["CategoryName"].ToString(), 
                                                  Convert.ToInt32(dtKat.Rows[i]["CategoryID"]),iPreSelected));
                    }
                    dbKat.dbDisConnect();

                    return returnment;
                }
            }

            public ItemVM(string sTitle, int iId, int iPreSelected)
            {
                this.sTitle = sTitle;
                this.iId = iId;
                this.iPreSelected = iPreSelected;
                if (iId == iPreSelected)
                    this.IsSelected = true;
            }
        }

iPreSelected ist die Id die vorselektiert werden soll.

ist der Ansatz richtig?

so wie ich das sehe, muss ich aber noch zwischen IsSelected und dem DataTrigger eine Verbindung herstellen, oder? wie mache ich das?

lg flo