Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
ListBox mit 'ObservableCollection' über DataContext füllen
sacoma
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

ListBox mit 'ObservableCollection' über DataContext füllen

beantworten | zitieren | melden

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:
Fehler
Für Binding "AutoListe" wurde kein DataContext gefunden.


Beim Ausführen des Programm kommt die Binding-Fehlermeldung:
Fehler
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}"; 
        }
    }
}

private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16.282

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
sacoma
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

Re:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Caveman
myCSharp.de - Member

Avatar #avatar-3854.jpg


Dabei seit:
Beiträge: 157

beantworten | zitieren | melden

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>
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16.282

beantworten | zitieren | melden

Zitat von sacoma
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.
Zitat von sacoma
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
private Nachricht | Beiträge des Benutzers
Sindelfinger
myCSharp.de - Member



Dabei seit:
Beiträge: 37
Herkunft: Deutschland

beantworten | zitieren | melden

Zitat von sacoma
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. ;-)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Sindelfinger am .
2 stupid 4 chess? No way.
2 stupid 4 C#? It seems so X(
private Nachricht | Beiträge des Benutzers
sacoma
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

Vielen Dank

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers