Laden...

View mittels Daten aus DB-Tabelle im Code-Behind erstellen

Letzter Beitrag vor einem Jahr 8 Posts 759 Views
View mittels Daten aus DB-Tabelle im Code-Behind erstellen

Hallo Leute,

ich bin, wie schon in meinen letzten Beitrag erwähnt, Anfänger in C# + WPF.

Ich arbeite seit ca. 3 Monaten in einer Firma, die mit C# und WPF Benutzer-Oberflächen (GUI) für Maschinen-Anlagen programmiert.

Momentan arbeite ich an der Ansicht (View) eines Programms für ein automatisch betriebenes Hochregallager.

Die View soll die Lagerplätze des Hochregallagers abbilden. Es sind über 400 Lagerplätze…

Es gibt eine Datenbank-Tabelle wo alle Lagerplätze (mit Infos, ob sie belegt sind oder nicht etc.) aufgelistet sind.

Jeder Lagerplatz ist in der View mittels einer Viewbox in einer bestimmten Reihenfolge/Anordnung dargestellt, die dem realen Hochregallager entspricht.

Die Viewbox beinhaltet ein Textblock mit der Lagerplatz-Nr.

Die Viewbox ist von einem Rahmen (Border) umgeben, das seine Farbe ändern soll, wenn der Lagerplatz, frei (grün), reserviert (gelb), belegt (rot) oder gesperrt (dunkelrot) ist.

Die über 400 Lagerplätze wollte ich (aus verständlichen Gründen) nicht von Hand in die WPF-Xaml-Datei eintragen, sondern habe sie im Code-Behind generieren lassen:

Zuerst wird eine Grid erstellt mit einer bestimmten Anzahl von Spalten und Zeilen, dann wird in eine Schleife mit Daten aus der Datenbank durchlaufen, in dem die Viewboxes mit den Textblock und Border erstellt werden. Die Lagerplatz-Nr. wird mittels Binding dem Textblock übergeben, das gleiche geschieht auch mit Farbe des Borders…

Allerdings gibt es nun Schwierigkeiten beim Data-Binding… Der Border ändert nicht wie gewünscht die Farbe… und ich frage mich, ob ich da auf den richtigen Weg bin oder als Anfänger das Pferd von hinten aufzäune…

Meine erste Frage lautet daher, ob es vielleicht eine bessere, schlauere Lösung in WPF gibt, die View zu erstellen… z.B.: irgendwie mit einem Data-Template in einem Xaml-Container, das in der Darstellung flexibler ist als DataGrid etc. von der ich als Anfänger nichts weiß.

Ich hänge ein Screenshot mit der hart gecodeten Darstellung der betreffenden View an, damit ihr eine Vorstellung habt wie das View aussehen soll...

Ich bin für alle Anregungen und Ideen dankbar.

LG,

sacoam

Lies dir bitte [Artikel] MVVM und DataBinding | myCSharp.de an, so wie du es machst ist das alles in WPF nicht gedacht.

Man erstellt im Codebehind keine Controls, sondern benutzt entsprechende Container die mit Item/Data/Hirarchical Templates ausgestattet werden.

Hallo FZelle,

dein Beitrag ist keine Antwort auf meine Frage - dass dies nicht so in WPF gedacht ist, ist mir selbst klar. Ich habe auch deshalb nach einer besseren Lösung gefragt.

Vielleicht sollte ich es anders formulieren:

Im DataGrid können Daten aus der Datenbank in einer Tabelle zeilenweise dargestellt werden.

Ich benötige eine andere, grafische Darstellung der Daten wie im Screenshot gezeigt.

LG,

sacoma

Ich denke, du benötigst ein ItemsControl, dass Du an eine Liste bindest.
Der Lagerplatz selbst ist ein Datatemplate, das dem ItemsControl als Template zugewiesen wird.
Im ViewModel gibt es dann eine ObservableCollection<Lagerplatz>.

<ItemsControl x:Name="ItemsControlRegal" 
              Grid.Row="1"
              ItemsSource="{Binding Lagerplaetze}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid x:Name="UniformGridIndices" Rows="5" Columns="6" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:Lagerplatz />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Hallo Caveman,

danke für die konstruktive Antwort. 😃

Ich werde mich dann mal mit dem ItemsControl befassen... 😉

LG,

sacoma

Hallo sacoma

Weil ich länger nichts mehr mit WPF gemacht habe, habe ich mir das Thema mal als Fingerübung genommen und Cavemans Ansatz weiterverfolgt.

Für die tabellenartige Darstellung ist nicht primär das ItemsControl relevant, sondern die Eigenschaft ItemsPanel. Die gibt es auch am ListView. Der Unterschied zwischen ItemsControl und ListView ist im wesentlichen das Selections-Verhalten.

Back to topic: Ich habe ein View für die Hochregale erstellt und eines für die Lagerplätze.

Lagerplatz aka RegalFach: der Status ist ein Enum und wird mit dem Converter in eine Farbe umgewandelt.

    <UserControl.Resources>
        <local:RegalFachStatusToBrushConverter x:Key="regalFachConverter"/>
    </UserControl.Resources>
    
    <ItemsControl ItemsSource="{Binding AllRegalFach}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="2" BorderBrush="{Binding Status, Converter={StaticResource regalFachConverter}}">
                    <TextBlock Text="{Binding Id}" />
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

HochregalViewModel hat eine ObservableCollection, die kann die UI über Änderungen benachrichtigen.

    public class HochregalViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<RegalFachViewModel> AllRegalFach { get; }

        public HochregalViewModel(IList<RegalFachViewModel> allRegalFach)
        {
            AllRegalFach = new ObservableCollection<RegalFachViewModel>(allRegalFach);
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string? name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

Mehrere Hochregale mit der ItemsPanel-Eigenschaft nebeneinander stellen:

    <ItemsControl ItemsSource="{Binding AllHochRegal}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:HochregalView />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Top" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

Damit solltest du schonmal was anfangen können. Den Rest kann man sich zusammenreimen.

Wichtig ist die Aufteilung zwischen ViewModel und Model. Das RegalFachViewModel (er)hält die Daten vom RegalFach. RegalFach kommt aus dem Repository, dass den Datenbank-Zugriff kapselt. MVVM ist eine Technik für die UI. Les dir dazu nochmal den von FZelle verlinkten Artikel durch und am Besten auch https://mycsharp.de/forum/threads/111860/artikel-drei-schichten-architektur.

Gruß
Alf

Hallo Alf Ator,

danke auch für deinen Beitrag - ich werde mich auch mit deinem Ansatz befassen - teilweise habe ich schon eine Lösung für mein Problem erstellt - nur mit der Darstellung der Lagerplätze am richtigen Platz auf GUI hagte es noch, aber mit deiner Lösung, weiß ich wie ich auch das hinkriegen kann.

Vielen Dank nochmal für deine Mühe. 😄

LG,

sacoma 😉

Danke an alle, die geholfen haben

Hallo Leute,

ich möchte mich nochmal für eure Hilfe bedanken.
Ich habe es geschafft die View wie gewünscht zu erstellen - ohne Code-Behind.

Danke an alle, die geholfen haben. 😃

LG,

sacoam 😉