Laden...

ListBox mit 'ObservableCollection' über DataContext füllen

Erstellt von sacoma vor einem Jahr Letzter Beitrag vor einem Jahr 834 Views
S
sacoma Themenstarter:in
23 Beiträge seit 2022
vor einem Jahr
ListBox mit 'ObservableCollection' über DataContext füllen

Hallo Leute,

ich bin Anfänger in C# und mache gerade ein paar Übungen in DataBinding.
Textboxen im Konstruktor mit DataContext zu füllen, beherrsche ich schon gut...

Ich versuche gerade eine ListBox über DataContext mit Daten von Autos (Datentyp ObservableCollection) zu füllen. Leider wird nichts in der Vorschau oder beim Ausführen des Programms angezeigt. 😠
Bei 'ItemsSource="{Binding AutoListe}"' wird der Wert 'AutoListe' mit drei Punkten markiert und wenn ich mit der Maus drübergehen, erscheint die Quick-Info:

Fehlermeldung:
Für Binding "AutoListe" wurde kein DataContext gefunden.

Beim Ausführen des Programm kommt die Binding-Fehlermeldung:

Fehlermeldung:
Die Eigenschaft "AutoListe" wurde im Objekt vom Typ "ObservableCollection`1" nicht gefunden.

Ich habe keine Ahnung was ich falsch mache - bei den Textboxen lief alles einwandfrei...

Hat jemand eine Idee?
Danke für jede Hilfe im Voraus. 🙂

LG,

sacoma

PS:

Hier ist mein Code von der UI 'SubTemplates3.xaml':


<Window x:Class="NeuesFensterWPF.SubTemplates3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NeuesFensterWPF"
        mc:Ignorable="d"
        Title="DataTemplates" Height="400" Width="400">
    <Grid>
        <ListBox Name="MyListBox"  Margin="10" ItemsSource="{Binding AutoListe}">

        </ListBox>
    </Grid>
</Window>

Hier ist mein Code von der Code-Behind 'SubTemplates3.xaml.cs':


namespace NeuesFensterWPF
{
    /// <summary>
    /// Interaktionslogik für SubTemplates3.xaml
    /// </summary>
    public partial class SubTemplates3 : Window
    {
        public SubTemplates3()
        {
            InitializeComponent();
            ObservableCollection<Auto> AutoListe = new ObservableCollection<Auto>
            {
                new Auto() { Marke = "Audi", Modell = "R8", PS = 610, Logo = "Images/logo_audi.jpg" },
                new Auto() { Marke = "Bentley", Modell = "CS", PS = 630, Logo = "Images/logo_bentley.jpg" },
                new Auto() { Marke = "Lambo", Modell = "LP 700", PS = 700, Logo = "Images/logo_lambo.jpg" },
                new Auto() { Marke = "SEAT", Modell = "DSG", PS = 300, Logo = "Images/logo_seat.jpg" },
                new Auto() { Marke = "Skoda", Modell = "RS", PS = 230, Logo = "Images/logo_skoda.jpg" },
                new Auto() { Marke = "VW", Modell = "TDI 8", PS = 240, Logo = "Images/logo_vw.jpg" }
            };

            DataContext = AutoListe; 
        }
    }
}

Hier wäre noch der Code aus der Klasse 'Auto' falls es von Bedeutung ist:


namespace NeuesFensterWPF
{
    public class Auto
    {
        public string Marke { get; set; }
        public string Modell { get; set;}
        public int PS { get; set; }
        public string Logo { get; set; }

        public override string ToString()
        {
            //base.ToString();
            return $"Marke: {Marke} | Modell: {Modell} | Leistung: {PS} | Logo: {Logo}"; 
        }
    }
}


16.807 Beiträge seit 2008
vor einem Jahr

In der XAML Bindest Du eine Eigenschaft mit dem Namen AutoListe


<ListBox Name="MyListBox"  Margin="10" ItemsSource="{Binding AutoListe}">

Aber Du hast kein ViewModel, das eine Eigenschaft AutoListe hat, sondern Du bindest die Liste direkt als DataContext


            DataContext = AutoListe;

AutoListe bei Dir ist eine Variable, die nur in der Methode SubTemplates3 (also dem Konstruktor) existiert.
Fehler passiert also daher, dass Du XAML etwas suchen lässt, das nicht existiert.

ObservableCollection sollte man i.d.R. nicht selbst erzeugen, sondern am ViewModel halten.
[Artikel] MVVM und DataBinding
Wenn Du die ObservableCollection in der Logik erzeugst (auch im VM) dann ist das eine neue Referenz, die dem XAML unbekannt ist - damit funktioniert das Binding nicht mehr.

Siehe auch Announcing .NET Community Toolkit 8.1! Better, faster MVVM source generators, .NET 7 support, and more!
Die Neuerungen rund um das Toolkit nehmen eine Menge ab, die man falsch machen kann.

PS: man überschreibt ToString eigentlich nicht für solch eine Ausgabelogik.
Das ist nicht unbedingt die Idee von ToString . Mach Dir daraus eine eigene Read-only Eigenschaft oder Methode.

S
sacoma Themenstarter:in
23 Beiträge seit 2022
vor einem Jahr
Re:

Hallo Abt,

danke für die schnelle Antwort.

Ich muss wohl noch eine Menge lernen, denn leider verstehe ich nur die Hälfte von was du da geschrieben hast... 🙁
Wie schon geschrieben: ich bin Anfänger und das sind nur Übungen, um mich mit C# + WPF + DataBinding vertraut zu machen (das man die "ToString"-Methode so in der Praxis nicht nutzt ist mir klar 😉 ).

Wie wäre nun der richtige Weg um das Binding der Liste hinzubekommen?

Ich habe schon im Internet recherchiert, aber noch nichts gefunden... 😠

LG,

sacoma

187 Beiträge seit 2009
vor einem Jahr

Erstelle ein ViewModel


public class MainWindowViewModel
    {
        public ObservableCollection<Auto> AutoListe { get; set; }

        public MainWindowViewModel()
        {
            AutoListe = new ObservableCollection<Auto>()
            {
                new Auto() { Marke = "Audi", Modell = "R8", PS = 610, Logo = "Images/logo_audi.jpg" },
                new Auto() { Marke = "Bentley", Modell = "CS", PS = 630, Logo = "Images/logo_bentley.jpg" },
                new Auto() { Marke = "Lambo", Modell = "LP 700", PS = 700, Logo = "Images/logo_lambo.jpg" },
                new Auto() { Marke = "SEAT", Modell = "DSG", PS = 300, Logo = "Images/logo_seat.jpg" },
                new Auto() { Marke = "Skoda", Modell = "RS", PS = 230, Logo = "Images/logo_skoda.jpg" },
                new Auto() { Marke = "VW", Modell = "TDI 8", PS = 240, Logo = "Images/logo_vw.jpg" }
            };
        }
    }

Erstelle eine Instanz des Viemodels in der View und definiere die Listbox. Das Datatemplate muss nach den Bedürfnissen angepasst werden.


<Window x:Class="MyCSharp125114.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyCSharp125114"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    
    <Grid>
        <ListBox Name="MyListBox"  Margin="10" ItemsSource="{Binding AutoListe}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Logo}" />
                        <TextBlock Margin="10, 0" Text="{Binding Marke}" />
                        <TextBlock Text="{Binding Modell}" />
                        <TextBlock Margin="10, 0" Text="{Binding PS}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

16.807 Beiträge seit 2008
vor einem Jahr

Ich habe schon im Internet recherchiert, aber noch nichts gefunden... 😠

Kurios, denn ich hab Dir [Artikel] MVVM und DataBinding gegeben, und genau da steht das drin 😉
WPF is so alt, so dermaßen weit verbreitet und so gut dokumentiert; ausgeschlossen, dass Du auf etwas stoßen wirst, bei dem Du nichts finden wirst.

Wie schon geschrieben: ich bin Anfänger und das sind nur Übungen, um mich mit C# + WPF + DataBinding vertraut zu machen

Mussten wir alle durch, nur dass Du Dir mit WPF leider eine Technologie ausgesucht hast, die eine eher höhere Lernkurve hat.
Man kommt da leider nicht drum herum Begrifflichkeiten zu nutzen, die Du lernen musst, wenn Du WPF machen möchtest; wobei das auf alle Binding-Technologien (WinForms, Angular, React..) im Endeffekt das gleiche/ähnliche ist.

Musst leider wirklich viel lesen, vor allem Basics.
What is Windows Presentation Foundation - WPF .NET

S
39 Beiträge seit 2019
vor einem Jahr

Ich habe schon im Internet recherchiert, aber noch nichts gefunden... 😠

Als ich mit WPF angefangen habe, war mein größtes Problem, die richtigen Suchbegriffe auszuwählen. Aber das kommt mit der Zeit.

Die Vorgehensweise mit dem ViewModel eröffnet Dir ungeahnte Möglichkeiten. Momentan fluchst Du wahrscheinlich noch mehr als Du tippst (so war's bei mir). Aber in 3 Monaten wirst Du es lieben. 😉

2 stupid 4 chess? No way.
2 stupid 4 C#? It seems so X(

S
sacoma Themenstarter:in
23 Beiträge seit 2022
vor einem Jahr
Vielen Dank

Hallo Leute!

Vielen Danke für eure Antworten - ich werde mich dann mehr ins MVVM-Patter vertiefen...

Ich weiß, dasss ich noch viel lernen muss.😉

LG,

sacoma

S
sacoma Themenstarter:in
23 Beiträge seit 2022
vor einem Jahr

Hallo Leute,

ich wollte euch nur mitteilen, dass ich jetzt den Bogen raus habe mit dem Befüllen der ListBox.
Ich danke für eure Hilfe und Hinweise.😘

LG,

sacoma🙂