Laden...

Forenbeiträge von Sascha87 Ingesamt 48 Beiträge

09.12.2021 - 12:44 Uhr

Warum machst Du das denn nicht im ViewModel?
Einfach die Liste mit den Rechten auf CanAddFPFoer filtern und einer zweiten Property zuweisen - oder direkt die erste Liste gefiltert anbieten.
Und wenn es immer nur ein Recht geben kann, suchst Du halt das eine Recht raus.
Dann brauchst Du den ganzen Kram nicht.

Ich bin absoluter Anfänger und verstehe den Ansatz nicht. Daher versuche ich mit Lösungen zurecht zu kommen, die es im Internet gibt.

Deinen Tipp werde ich versuchen, vielen lieben Dank!

09.12.2021 - 06:59 Uhr

Das Anzeigen und Nicht-Anzeigen des Buttons habe ich hinbekommen.
Ich habe einfach eine Liste um den Button erstellt. Dort konnte ich ItemsSource und SelectedItem anwenden. Jetzt kann ich nur nicht mehr auf den Command des Buttons zugreifen.

Dem Binding habe ich ein "RelativeSource" hinzugefügt. Die eigentliche Bindung zum Command funktioniert. Allerdings führt er nichts aus.


<UserControl.DataContext>
        <vm:ViewModel></vm:ViewModel>
    </UserControl.DataContext>


<ListBox ItemsSource="{Binding Rechte, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding ProRechte, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="{Binding SelectedFont, UpdateSourceTrigger=PropertyChanged}" BorderThickness="0" Background="WhiteSmoke">
                                        <ListBox.ItemContainerStyle>
                                            <Style TargetType="ListBoxItem">
                                                <Setter Property="Visibility" Value="{Binding CanAddFPFoer, Converter={StaticResource BoolToVis}}" />
                                            </Style>
                                        </ListBox.ItemContainerStyle>
                                        <ListBox.ItemTemplate>
                                            <DataTemplate>
                                                <StackPanel Orientation="Horizontal">
                                                    <Button Content="Eintragen" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type vm:ViewModel}}, Path=FoerderEintragen}" Padding="5 5 5 5" Margin="5 15 5 0" />
                                                </StackPanel>
                                            </DataTemplate>
                                        </ListBox.ItemTemplate>
                                    </ListBox>


Als Bindungsfehler taucht folgendes aus: > Fehlermeldung:

Quelle nicht gefunden: RelativeResource FindAncestor, AncestorType="ViewModel", AncestorLevel="1"

Hätte jemand einen heißen Tipp für mich?
Vielen lieben Dank und einen guten Start in den Tag!
Grüße
Sascha

08.12.2021 - 16:05 Uhr

Das war der entscheidende Hinweis!

Vielen lieben Dank!

Grüße
Sascha

08.12.2021 - 13:03 Uhr

Das habe ich bisher noch nicht benötigt. Wie gebe ich dem denn Rechte?

08.12.2021 - 12:56 Uhr

Im getter steht er anscheinend auf Null....

08.12.2021 - 12:26 Uhr

Ok, ich glaube, ich bin ein Schritt weiter.

Ich habe jetzt die folgende Property erstellt:


Recht _rechte;
        public Recht ProRechte
        {
            get
            {
                return _rechte;
            }
            set
            {
                if (value == null)
                    return;
                OnPropertyChanged(ref _rechte, value);
            }
        }

Im xaml Code kann ich auf den Wert zugreifen:


<Button Content="Löschen" Command="{Binding FoerderLoeschen}" FontSize="{Binding SelectedFont, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ProRechte.CanDelFPFoer, Converter={StaticResource BoolToVis}}" Padding="5 5 5 5" Margin="5 15 5 0"/>

Nur gibt er mir keinen Wert aus?
Was ich vorhabe: Ich habe in der Datenbank eine 1 oder NULL gespeichert.
Ich lese die Werte als Nullable Bool aus und gebe sie als Liste weiter.

Ich möchte die Buttons anzeigen oder verstecken, je nach Wert. Dazu gibt es den BooleanToVisibilityConverter.

Allerdings wandelt er es nicht um bzw. ich vermute, dass ich meinen Wert nicht bekomme. Kann ich irgendwie überprüfen, ob true oder false ankommt?

Vielen lieben Dank!

08.12.2021 - 11:19 Uhr

Hättest du eventuell einen Tipp wie ich innerhalb einer Property nur auf ein Element der Klasse zugreife?

EDIT: Hat sich erledigt.

08.12.2021 - 10:27 Uhr

Guten Morgen zusammen,
ich möchte ein ItemsSource an ein Button Binden. Der Grund ist, ich benötige Unterwerte einer Klasse.

Bei einer ListBox kann ich "Rechte" als ItemsSource Binden und in den ListBox.ItemTemplates kann ich tiefer darauf zugreifen (Rechte.HatRechte).

Leider geht es bei den Buttons nicht. Dort kann ich nur "Rechte" Binden. Nach ein wenig googln kam ich auf die Funktion "ItemsControl".


<ItemsControl ItemsSource="{Binding Rechte}" >
                                            <ItemsControl.ItemTemplate>
                                                <DataTemplate>
                                                    <StackPanel>
                                                        <Button Content="Löschen" Command="{Binding FoerderLoeschen}" FontSize="{Binding SelectedFont, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding Rechte.CanDelFPFoer, Converter={StaticResource BoolToVis}}" Padding="5 5 5 5" Margin="5 15 5 0"/>
                                                    </StackPanel>
                                                </DataTemplate>
                                            </ItemsControl.ItemTemplate>
                                        </ItemsControl>

Soweit kann ich "Rechte" Binden und in dem Button auf "Rechte.CanDelFPFoer" zugreifen. Mein Problem ist, ich bekomme für jeden Unterwert einen Button ausgegeben. Sprich statt 1 Button bekomme ich in dem Fall 30. Wie kann ich das auf 1 Button begrenzen? Gibt es eine Alternative zu ItemsControl? Gehe ich die Sache komplett falsch an?

Vielen lieben Dank und Grüße
Sascha

13.07.2021 - 17:46 Uhr

Gut, dann anders.

Wenn ich die Methode von Th69 richtig verstehe, wird nur der Wert an die URL gehängt, der auch gefüllt ist, richtig?

Ich bekomme auf der anderen Seite dann Schwierigkeiten. Das Script auf dem Server erwartet genau die URL.
Woher soll das Script denn wissen, wenn die Werte in einer ganz anderen Reihenfolge versendet werden?

13.07.2021 - 17:33 Uhr

Gibt es die Möglichkeit, wenn ich keinen Wert habe, dass dann "-" gesetzt wird?

Auch, wenn es nicht der Ansicht von Abt entspricht, finde ich den Weg ganz gut. So hätte ich keine leeren Felder in der DB und beim auslesen habe ich direkt ein Zeichen in der Liste, das zeigt, dass dort keine Werte vorhanden sind und ergänzt werden müssen.
Denn genau das Zeichen setze ich so oder so als


TargetNullValue=-

13.07.2021 - 16:12 Uhr

Leider nein. Mir würde ein Default Value wie "-" reichen.

13.07.2021 - 15:31 Uhr

Du hast recht, die Methode wird immer aufgerufen.

Mein RestAPI Link wird nur nicht korrekt gefüllt. Daher gibt es auch keine Einträge in der Datenbank.

13.07.2021 - 14:05 Uhr

Vielen lieben Dank Th69!
Soweit klappt alles.
Das Einzige, das mir aufgefallen ist, der Speichert die Daten erst in der Datenbank, wenn man alle Zellen einmal angeklickt hat.
Manche Zellen sollen zwischendurch leer bleiben. Wäre das in der Umsetzung noch möglich? Oder muss ich eher auf CellEditEnding gehen?

13.07.2021 - 09:59 Uhr

Das hatte ich ursprünglich. Leider bekomme ich beim JSon Objekten Probleme:


var arr = JsonConvert.DeserializeObject<JArray>(restResponse.Content);
                    foreach (JObject obj in arr)
                    {
                        var KompetenzID = (string)obj["id"];
                        var Kompetenz = (string)obj["Kompetenz"];
                        var SHDID = (string)obj["SHDID"];
                        var Ergebnis = (string)obj["Ergebnis"];
                        var Stufe = (string)obj["Stufe"];
                        var Niveau = (string)obj["Niveau"];
                        var Note = (string)obj["Note"];
                        DateTime Datum = (DateTime)obj["Datum"];
                        var Kuerzel = (string)obj["Kuerzel"];
                        var background = (string)obj["background"];

                        _kompetenzen.Add(new LDKompetenz(KompetenzID, Kompetenz, SHDID, Ergebnis, Stufe, Niveau, Note, Datum, Kuerzel, background, name, ViewFingerPrint));
                    }

Ich habe Tabelle 1 mit 20 Daten. In Tabelle 2 habe ich die Nutzerinformationen dazu. Nicht zu jeder Zeile aus Tabelle 1 gibt es Nutzerdaten. Daher kann es passieren, dass DateTime Datum = null ist.
Dann bekomme ich eine Fehlermeldung (siehe Bild).

13.07.2021 - 09:32 Uhr

Vielen vielen Dank! Mein Verständnis erweitert sich und es funktioniert fast.

Ein einziges Problem habe ich noch. Das Datum gebe ich als String weiter.

Den string ändere ich ab, damit es kein Backslash im string ist


var newdate = Datum.Replace(@"/", "-");

Allerdings lässt er die Uhrzeit. Wie bekomme ich die wohl weg?

12.07.2021 - 21:32 Uhr

Nachträglich noch der Tipp:
Wenn du Strings hardcoden musst, dann macht das über Konstanten.
Literale im Code sind eine sehr unschöne Sache und gehen auch bei einigen Umsetzungen auch in Richtung Magic Strings.

Auch wäre es besser wenn du anstelle von "" als Wert String.Empty verwendest.
Durch "" im Code erzeugst du zusätzliche Literale, was die Laufzeitumgebung zwar abfängt aber durch String.Empty wird eine statische Instanz verwendet und der Code ist auch klarer ausgedrückt.

Auch würde ich empfehlen die Deserialierung des Json umzubauen.
Was du im Grund hast, ist eine Liste von Objekten.
Du kannst hier einfach List<T> als Container verwenden und eine entsprechende Klasse anlegen, die ein einzelnes Objekt der Api abbildet.
Dadurch sparst du dir den Aufwand die Eigenschaften einzeln auslesen und die Liste selbst aufbauen zu müssen.
Kann an der Stelle der Deseralisierer übernehmen.
Spart dir unnötigen Aufwand und Zeit bei der Umsetzung 🙂

T-Virus

Ok, danke für die Tipps! Dann werde ich mir mal anschauen wie es mit den Listen funktioniert.

12.07.2021 - 21:29 Uhr

Ok, das teste ich mal.

Ich benötige noch die Variabel "Name" aus der ViewModel. Das ist eine TextBox aus der View.

Dazu habe ich folgendes in der ViewModel:


        private string _name = "1";
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (value == "" && value == null)
                    return;
                _name = value;
                LDKompetenzen = LDKompetenzen.Load(LDCurrentFach.FachID, LDCurrentThema.ThemaID, ViewFingerPrint, Name);
                OnPropertyChanged(ref _name, value);
            }
        }

Kann ich es ganz normal mit Name {get set} in der LDKompetenz laden?

12.07.2021 - 21:03 Uhr

Das ist hier meine Klasse:



class LDKompetenzen : ObservableCollection<LDKompetenz>
    {
        private static readonly LDKompetenzen _kompetenzen = new LDKompetenzen();

        private LDKompetenzen() { }

        public static LDKompetenzen Load(string fachID, string themenID, string ViewFingerPrint, string name)
        {
            _kompetenzen.Clear();
            try
            {
                var client = new RestClient("MEINEDOMAIN");

                var request = new RestRequest("ld/kompetenzen/{fachid}/{themenid}/{SHDID}", Method.GET)
                .AddHeader("Authorization", "Bearer " + ViewFingerPrint)
                .AddUrlSegment("fachid", fachID)
                .AddUrlSegment("SHDID", name)
                .AddUrlSegment("themenid", themenID);

                IRestResponse restResponse = client.Execute(request);
                HttpStatusCode statusCode = restResponse.StatusCode;
                if ((int)statusCode != 401)
                {
                    var arr = JsonConvert.DeserializeObject<JArray>(restResponse.Content);
                    foreach (JObject obj in arr)
                    {
                        var KompetenzID = (string)obj["id"];
                        var Kompetenz = (string)obj["Kompetenz"];
                        var SHDID = (string)obj["SHDID"];
                        var Ergebnis = (string)obj["Ergebnis"];
                        var Stufe = (string)obj["Stufe"];
                        var Niveau = (string)obj["Niveau"];
                        var Note = (string)obj["Note"];
                        var Datum = (string)obj["Datum"];
                        var Kuerzel = (string)obj["Kuerzel"];
                        var background = (string)obj["background"];

                            _kompetenzen.Add(new LDKompetenz(KompetenzID, Kompetenz, SHDID, Ergebnis, Stufe, Niveau, Note, Datum, Kuerzel, background));
                    }
                }
                else
                {
                    var KompetenzID = "0";
                    var Kompetenz = "";
                    var SHDID = "";
                    var Ergebnis = "";
                    var Stufe = "";
                    var Niveau = "";
                    var Note = "";
                    var Datum = "";
                    var Kuerzel = "";
                    var background = "white";

                    _kompetenzen.Add(new LDKompetenz(KompetenzID, Kompetenz, SHDID, Ergebnis, Stufe, Niveau, Note, Datum, Kuerzel, background));
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            return _kompetenzen;
        }
    }

Und die greift auf folgende zu:



        public LDKompetenz(string kompetenzID, string kompetenz, string shdID, string ergebnis, string stufe, string niveau, string note, string datum, string kuerzel, string background)
        {
            KompetenzID = kompetenzID;
            Kompetenz = kompetenz;
            SHDID = shdID;
            Ergebnis = ergebnis;
            Stufe = stufe;
            Niveau = niveau;
            Note = note;
            Datum = datum;
            Kuerzel = kuerzel;
            Background = background;
        }

        //Anzeige Fördermaßnahmen
        public string KompetenzID { get; set; }
        public string Kompetenz { get; set; }
        public string SHDID { get; set; }
        public string Ergebnis { get; set; }
        public string Stufe { get; set; }
        public string Niveau { get; set; }
        public string Note { get; set; }
        public string Datum { get; set; }
        public string Kuerzel { get; set; }
        public string Name { get; set; }
        public string Background { get; set; }

        public bool IsSelected { get; set; }

        public override string ToString()
        {
            return $"{Kompetenz}";
        }
    }


12.07.2021 - 20:37 Uhr

Ok, dann habe ich das falsch verstanden.

Die LDKompetenzen hole ich so in das ViewModel:


public LDKompetenzen LDKompetenzen { get; set; }

So lade ich die "Current" Version:


LDKompetenz _ldcurrentKompetenz = null;
        public LDKompetenz LDCurrentKompetenz
        {
            get { return _ldcurrentKompetenz; }
            set
            {
                if (value == null)
                    return;
                OnPropertyChanged(ref _ldcurrentKompetenz, value);
            }
        }

So lade ich die Daten in die View:


LDKompetenzen = LDKompetenzen.Load(LDCurrentFach.FachID, value.ThemaID, ViewFingerPrint, Name);

12.07.2021 - 20:21 Uhr

Das ist meine ViewModel.
In deinem Beispiel sowie unzählige andere wurde es dort implementiert.

12.07.2021 - 17:55 Uhr

Also, folgendes habe ich gemacht:

ViewModel:
Die Klasse erweitert:


class LDViewModel : NotifyPropertyBase, IEditableObject

Anschließend folgendes gefüllt:


    public void EndEdit()
        {
            var client = new RestClient("https://xxxxxxxxde/");
            var request = new RestRequest("ld/LDUpdate/{name}/{kompetenzID/{ergebnis}/{stufe}/{niveau}/{note}/{datum}/{kuerzel}", Method.POST)
                .AddUrlSegment("name", Name)
                .AddUrlSegment("kompetenzID", LDCurrentKompetenz.KompetenzID)
                .AddUrlSegment("ergebnis", LDCurrentKompetenz.Ergebnis)
                .AddUrlSegment("stufe", LDCurrentKompetenz.Stufe)
                .AddUrlSegment("niveau", LDCurrentKompetenz.Niveau)
                .AddUrlSegment("note", LDCurrentKompetenz.Note)
                .AddUrlSegment("datum", LDCurrentKompetenz.Datum)
                .AddUrlSegment("kuerzel", LDCurrentKompetenz.Kuerzel)
                .AddHeader("Authorization", "Bearer " + ViewFingerPrint);

            IRestResponse restResponse = client.Execute(request);

            if (restResponse.StatusCode == HttpStatusCode.BadRequest)
            {
                MessageBox.Show("Irgendetwas stimmt mit der Verbindung nicht.");
            }
            else
            {
                MessageBox.Show("Die Leistungsdokumentation wurde erfolgreich aktualisiert.");
            }
        }

Allerdings reagiert er nicht. Woher weiß er, welches DataGrid gemeint ist?

12.07.2021 - 16:01 Uhr

Genau, die Klasse ist als ObservableCollection deklariert. In diese Klasse kann ich dann eine weitere Methode mit IEditableObject einfügen?
Es tut mir Leid, es ist Neuland für mich 🙄

12.07.2021 - 15:51 Uhr

Ich weiß nicht was mich da geritten hat.....4.7.2 meine ich.

12.07.2021 - 15:03 Uhr

Vielen Dank für die Links.
Beim ersten Link: Ich nutze .NET 4,75 (Galasoft geht nur bis 4.5). Daher kann ich keine "Galasoft WPF" hinzufügen.

Link 2: Ich nutze in meiner ViewModel INotifyPropertyChanged.

Funktioniert es, wenn ich eine entsprechende Funktion in die Viewmodel schreibe mit IEditableObject?

12.07.2021 - 08:29 Uhr

Verwendetes Datenbanksystem: MariaDB
Verwendete API: RestSharp

Hallo zusammen,
erneut habe ich eine Frage.
Aktuell lade ich einige Daten per RestApi in ein DataGrid. Die Anzeige, der darin enthaltenen Daten funktioniert soweit ganz gut.
Jetzt möchte ich die einzelnen Zeilen abändern und automatisch in der Datenbank speichern können.
Das speichern sollte ebenfalls mittels RestSharp funktionieren.

Nur, wie gehe ich da am besten vor? Wie bekomme ich die Inhalt der einzelnen Zeilen eines DataGrid.
Wie speichere ich den geänderten Wert automatisch? Oder geht es nur per Button?

Hier mein Code:


<DataGrid ItemsSource="{Binding LDKompetenzen}" AutoGenerateColumns="False" CanUserDeleteRows="False" CanUserAddRows="False" CanUserSortColumns="True" FontSize="12" Height="Auto" BorderThickness="0">
                <DataGrid.Resources>
                    <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}" >
                        <Setter Property="Background" Value="LightGray" />
                        <Setter Property="Foreground" Value="Black" />
                        <Setter Property="BorderBrush" Value="Black"/>
                        <Setter Property="BorderThickness" Value="1 1 1 1"/>
                        <Setter Property="Margin" Value="-1,-1,0,0" />
                        <Setter Property="Height" Value="28" />
                        <Setter Property="Width" Value="auto"/>
                        <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        <Setter Property="FontWeight" Value="SemiBold"/>
                        <Setter Property="FontStyle" Value="Italic"/>
                        <Setter Property="FontSize" Value="15"/>
                        <Setter Property="Padding" Value="15,0,15,0"/>
                    </Style>
                </DataGrid.Resources>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Kompetenz" Binding="{Binding Kompetenz}" IsReadOnly="True">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="TextBlock.Background" Value="{Binding Background}" />
                                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                                <Setter Property="VerticalAlignment" Value="Stretch"/>
                                <Setter Property="TextAlignment" Value="Center"/>
                                <Setter Property="Padding" Value="0,20,0,0"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTemplateColumn Header="Farben" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                    <Button Content="" Background="White" Margin="2" Padding="5,3,5,3"></Button>
                                    <Button Content="" Background="Yellow" Margin="2" Padding="5,3,5,3"></Button>
                                    <Button Content="" Background="LightGreen" Margin="2" Padding="5,3,5,3"></Button>
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Header="Stufe" Binding="{Binding Stufe, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" >
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTextColumn Header="Niveau" Binding="{Binding Niveau, UpdateSourceTrigger=LostFocus, Mode=TwoWay}">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTextColumn Header="Ergebnis" Binding="{Binding Ergebnis, UpdateSourceTrigger=LostFocus, Mode=TwoWay}">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTextColumn Header="Note" Binding="{Binding Note, UpdateSourceTrigger=LostFocus, Mode=TwoWay}">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTemplateColumn Header="Datum">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <DatePicker SelectedDate="{Binding Datum, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" BorderThickness="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Header="Kürzel" Binding="{Binding Kuerzel, UpdateSourceTrigger=LostFocus, Mode=TwoWay}">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>

Ich bin für einige Gedankenansetze von euch sehr Dankbar!

Grüße
Sascha

05.07.2021 - 11:06 Uhr

Es ging mir nur im meinen letzten Post und nicht um den kompletten Thread. Ich hatte ursprünglich eine Frage gestellt die sich erledigt hat.

04.07.2021 - 14:22 Uhr

Es hat sich erledigt. Post bitte löschen.

20.06.2021 - 09:47 Uhr

Vielen Dank für die vielen Tipps! Ich werde mir das ganze anschauen und mein Script entsprechend anpassen.

Ich bin aktuell bei der Authentifizierung und Autorisierung.

In C# nutze ich RestSharp.

Mit:


var client = new RestClient("http://example.com");
client.Authenticator = new SimpleAuthenticator("username", "foo", "password", "bar");

var request = new RestRequest("resource", Method.GET);
client.Execute(request);

schicke ich die Anfrage an den Server und bekommen die Info, ob die Anmeldedaten passen, zurück. Soweit verständlich.

Auf der anderen Seite nutze ich Lumen (Laravel). Dort muss ich die Daten annehmen und prüfen. Es gibt grundsätzlich bei mir keine Useraccounts. Soll ich extra eine Tabelle anlegen und mit dieser vergleichen? Macht das Sinn?

Wenn ich in RestSharp den Benutzername und das Passwort einfüge, kann das Programm nicht dennoch "ausgelesen" werden und die Zugangsdaten sind offen?

Über hilfreiche Tipps wäre ich sehr Dankbar!
Liebe Grüße und einen schönen Sonntag noch!
Sascha

18.06.2021 - 22:05 Uhr

Das war der passende Tipp, vielen lieben Dank!

18.06.2021 - 20:48 Uhr

Vielen Dank für deine Tipp!
Die Authentifizierung kommt später. Als Anfänger baue ich eins nach dem anderen aus. Es muss für mich erst die Grundfunktion klappen bevor ich es "zubaue".
Ich weiß, eine seltsame Herangehensweise, aber so lerne ich am besten.

Ich habe jetzt, mittels json_encode die Daten umgewandelt.


[url]https://api.heinrich-luebke-schule.de/api/faecher[/url]

Leider kommt der gleiche Fehler.

Wie genau prüfst du, ob die Daten als json zurück geliefert werden?

Liebe Grüße
Sascha

18.06.2021 - 17:03 Uhr

Hallo zusammen,
vielen Dank für eure Hilfestellungen, die haben mich schon etwas voran gebracht.

Aktuell habe ich es hinbekommen, dass Daten per URL angezeigt werden. Allerdings als array object und nicht als JSON.

Hat jemand von euch die Daten aus einem Array weiter verarbeitet?

Ich habe es mit JObject versucht, da ich zuerst dachte die Daten würden als JSON weitergegeben werden.


var client = new RestClient("https://daustausch.heinrich-luebke-schule.de/ReadAPI/faecher");
                var request = new RestRequest(Method.GET);
                

                IRestResponse restResponse = client.Execute(request);

                string response = restResponse.Content;
                var jObject = JObject.Parse(restResponse.Content);

                string fachID = jObject.GetValue("id").ToString();
                string fach = jObject.GetValue("fach").ToString();

                _faecher.Add(new Fach(fachID, fach));

Die Daten werden bis hier hin erfolgreich geladen:
string response = restResponse.Content;

Nachdem er es Parsen soll, sagt er das es nicht das richtige Format sei (logisch).

Ich nutze das "Slim Framework" zum Auslesen der Datenbank und Bereitstellung.
Eventuell gibt es noch eine Alternative, dass Array weiter zu verarbeiten?

Liebe Grüße und vielen Dank!
Sascha

12.06.2021 - 12:21 Uhr

Verwendetes Datenbanksystem: MySQL (MariaDB)

Hallo zusammen,
aktuell greife ich auf eine entfernte Datenbank zu. Ich würde gerne davon weg kommen und suche aufgrund dessen eine Alternative.
Jetzt habe ich öfters gelesen, dass eine RestAPI dafür gut sein soll. Auf der Suche via Google bin ich auf RestSharp gestoßen.

Kann jemand RestSharp empfehlen oder empfiehlt generell etwas anderes als eine RestAPI?

Liebe Grüße
Sascha

01.06.2021 - 20:06 Uhr

Super, vielen lieben Dank an euch! Ich bin zumindest ein Schritt weiter. Auch was das Verständnis angeht. Aber leider gibt es direkte das nächste Problem.

Aktuell gebe ich alle Werte aus und werden angezeigt. Ich habe an den ListBoxen/ComboBoxen SelectedIndex="0". Dadurch werden die ersten Werte angezeigt. Sobald ich das Fach wechsel, bekomme ich die Meldung

Fehlermeldung:
System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

"value" war "null".

Zum Verständnis habe ich ein Bild angehängt. Die Frage ist, wie bekomme ich es hin, dass er die Nachfolgenden ComboBoxen/ListBoxen aktualisiert bzw. den Index auf 0 setzt?

meine ViewModel.cs:


class ViewModel : NotifyPropertyBase
    {

        public Faecher Faecher { get; set; }
        public Jahrgaenge Jahrgaenge { get; set; }
        public UVorhabens UVorhabens { get; set; }
        public Kompetenzen Kompetenzen { get; set; }
        public Foerdermaßnahmen Foerdermaßnahmen { get; set; }
        public ICommand RefreshCommand { get; set; }
        public Fach SelectedFachID { get; set; }


        Fach _currentFach = null;
        public Fach CurrentFach
        {
            get { return _currentFach; }
            set
            {
                Jahrgaenge = Jahrgaenge.Load(value.FachID);
                OnPropertyChanged(ref _currentFach, value);
            }
        }

        Jahrgang _currentJahrgang = null;
        public Jahrgang CurrentJahrgang
        {
            get { return _currentJahrgang; }
            set
            {
                UVorhabens = UVorhabens.Load(CurrentFach.FachID, value.JahrgangID);
                OnPropertyChanged(ref _currentJahrgang, value);
            }
        }

        Unterrichtsvorhaben _currentUVorhaben = null;
        public Unterrichtsvorhaben CurrentUVorhaben
        {
            get { return _currentUVorhaben; }
            set
            {
                Kompetenzen = Kompetenzen.Load(CurrentJahrgang.JahrgangID, value.UvID);
                OnPropertyChanged(ref _currentUVorhaben, value);
            }
        }

        Foerdermaßnahme _currentFoerdermaßnahme = null;
        public Foerdermaßnahme CurrentFoerdermaßnahme
        {
            get { return _currentFoerdermaßnahme; }
            set
            {
                Foerdermaßnahmen = Foerdermaßnahmen.Load(CurrentJahrgang.JahrgangID, CurrentUVorhaben.UvID);
                OnPropertyChanged(ref _currentFoerdermaßnahme, value);
            }
        }

        public ViewModel()
        {
            Faecher = Faecher.Load();
            RefreshCommand = new DelegateCommand(OnRefresh, OnCanRefresh);
        }

        private bool OnCanRefresh(object parameter)
        {
            return NetworkInterface.GetIsNetworkAvailable();
        }

        private void OnRefresh(object parameter)
        {
            Faecher = Faecher.Load();
            Jahrgaenge = Jahrgaenge.Load(CurrentFach.FachID);
            UVorhabens = UVorhabens.Load(CurrentFach.FachID, CurrentJahrgang.JahrgangID);
            Kompetenzen = Kompetenzen.Load(CurrentUVorhaben.UvID, CurrentJahrgang.JahrgangID);
            Foerdermaßnahmen = Foerdermaßnahmen.Load(CurrentUVorhaben.UvID, CurrentJahrgang.JahrgangID);
        }
    }

Es tut mir Leid, dass ich euch öfters Frage. Ich google auch vorher, wenn ich einen Ansatz habe. Aber irgendwie funktioniert kein Beispiel, dass ich gefunden habe.

30.05.2021 - 19:09 Uhr

@TH69

Dann mußt du auch die Auswahl der ComboBox (SelectedValue) als ViewModel-Eigenschaft erstellen (und per XAML binden) und diese dann in den weiteren ViewModel-Methoden verwenden.

Hättest du ein Beispiel- Code für mich?

Außerdem solltest du dir auch mal [Artikel] Drei-Schichten-Architektur durchlesen: Datenbankabfragen sollten nicht im ViewModel (Logik) durchgeführt werden, sondern in einer eigenen Datenzugriffsklasse (-schicht).

Die Datenbankabfrage findet nicht in der ViewModel statt.

Und sowohl MySqlCommand als auch MySqlDataReader sollten per using-Anweisung umschlossen sein - dann benötigst du auch kein manuelles Close() mehr.

Wird gemacht.

@Chilic

Lösung: Gib den zu suchenden Wert als Parameter in die Methode Load() hinein.

Ich frage nur ungern, aber kannst du mir ein Beispiel geben?

Ich bin euch unendlich Dankbar für eure Hilfe!

30.05.2021 - 14:00 Uhr

Ok, einmal von vorn.

Ich habe folgende Klassen:

Fach.cs


public class Fach
    {
        public Fach(string fachID, string fach)
        {
            FachID = fachID;
            FachName = fach;
        }

        //Anzeige Fächer
        public string FachID { get; set; }
        public string FachName { get; set; }

        public override string ToString()
        {
            return $"FachID:{FachID},Fach:{FachName}";
        }

        internal void Add(Fach fach)
        {
            throw new NotImplementedException();
        }
    }

Faecher.cs


public class Faecher : ObservableCollection <Fach>
    {
        private static Faecher _faecher = new Faecher();
        private Faecher() { }
        public static Faecher Load()
        {
            _faecher.Clear();
                 using (var sqlConnection = new MySqlConnection(Properties.Settings.Default.DBConnectionString))
                {
                    sqlConnection.Open();
                    //Daten aus der Tabelle lesen
                    string query = "select * from faecher order by fach asc";
                    MySqlCommand cmd = new MySqlCommand(query, sqlConnection);
                    
                    MySqlDataReader reader = cmd.ExecuteReader();

                    //Daten in fachtable füllen
                    while (reader.Read())
                    {
                        string fachID = reader.GetString("id");
                        string fach = reader.GetString("fach");

                        _faecher.Add(new Fach(fachID, fach));
                    }
                    reader.Close();
                    sqlConnection.Close();
            }
            return _faecher;
        }
    }

ViewModel.cs


class ViewModel : NotifyPropertyBase
    {
        public Faecher Faecher { get; set; }
        public Jahrgaenge Jahrgaenge { get; set; }

        public ICommand RefreshCommand { get; set; }

        public ViewModel()
        {
            Faecher = Faecher.Load();
            Jahrgaenge = Jahrgaenge.Load();
            RefreshCommand = new DelegateCommand(OnRefresh, OnCanRefresh);
        }

        private bool OnCanRefresh(object parameter)
        {
            return NetworkInterface.GetIsNetworkAvailable();
        }

        private void OnRefresh(object parameter)
        {
            Faecher = Faecher.Load();
            Jahrgaenge = Jahrgaenge.Load();
        }
    }

Die Übergabe an das WPF damit funktioniert super. Die Fächer (Fächer-Name) und die Fach ID wird übergeben und angezeigt. Jetzt möchte ich, dass die ID, nach der Auswahl der ComboBox an die
Jahrgaenge.cs übergeben wird mit folgendem Inhalt:


class Jahrgaenge : ObservableCollection <Jahrgang>
    {
        private static Jahrgaenge _jahrgaenge = new Jahrgaenge();

        private Jahrgaenge() { }

          public static Jahrgaenge Load()
        {
            _jahrgaenge.Clear();
            using (var sqlConnection = new MySqlConnection(Properties.Settings.Default.DBConnectionString))
            {
                sqlConnection.Open();
                //Daten aus der Tabelle lesen
                

                string query = "select * from jahrgang a inner join faecherJahrgang fj on a.id = fj.jahrgangID where fj.faecherID = @fachID";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                cmd.Parameters.AddWithValue("@fachID", listFach.SelectedValuePath);

                MySqlDataReader reader = cmd.ExecuteReader();

                //Daten in fachtable füllen
                while (reader.Read())
                {
                    string jahrgangID = reader.GetString("id");
                    string jahrgang = reader.GetString("jahrgang");

                    _jahrgaenge.Add(new Jahrgang(jahrgangID, jahrgang));
                }
                reader.Close();
                sqlConnection.Close();
            }
            return _jahrgaenge;
        }
    }

Ich hoffe, es bringt ein bischen mehr Licht ins dunkle. Ich bin "leider" noch Anfänger und probiere mich am MVVM Pattern.

30.05.2021 - 09:07 Uhr

Das hier übergebe ich an das WPF Formular. Die fachID kommt vor.


public static Faecher Load()
        {
            _faecher.Clear();
                 using (var sqlConnection = new MySqlConnection(Properties.Settings.Default.DBConnectionString))
                {
                    sqlConnection.Open();
                    //Daten aus der Tabelle lesen
                    string query = "select * from faecher order by fach asc";
                    MySqlCommand cmd = new MySqlCommand(query, sqlConnection);
                    
                    MySqlDataReader reader = cmd.ExecuteReader();

                    //Daten in fachtable füllen
                    while (reader.Read())
                    {
                        string fachID = reader.GetString("id");
                        string fach = reader.GetString("fach");

                        _faecher.Add(new Fach(fachID, fach));
                    }
                    reader.Close();
                    sqlConnection.Close();
            }
            return _faecher;
        }

30.05.2021 - 08:19 Uhr

Verwendetes Datenbanksystem: MySQL / MariaDB

Hallo zusammen,
ich bin aktuell dabei mein komplettes Script auf das MVVM Pattern umzuschreiben.
Es geht um dieses Projekt: Link

Die erste ComboBox fülle ich erfolgreich mit Werten aus der Datenbank per Databinding.


<ComboBox Name ="listFach" ItemsSource="{Binding Faecher}" SelectedIndex="0">
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock x:Name="FachID" Text="{Binding Path=FachID}" />
                                <TextBlock Text=" - " />
                                <TextBlock Text="{Binding Path=FachName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>

Die FachID lasse ich mir aktuell anzeigen, soll später, wenn möglich, nicht Sichtbar sein.

Diese genannte FachID möchte ich wieder zurück übergeben, da ich den Wert für eine Select Abfrage benötige.


class Jahrgaenge : ObservableCollection <Jahrgang>
    {
        private static Jahrgaenge _jahrgaenge = new Jahrgaenge();

        private Jahrgaenge() { }

        public static Jahrgaenge Load()
        {
            _jahrgaenge.Clear();
            using (var sqlConnection = new MySqlConnection(Properties.Settings.Default.DBConnectionString))
            {
                sqlConnection.Open();
                //Daten aus der Tabelle lesen
                

                string query = "select * from jahrgang a inner join faecherJahrgang fj on a.id = fj.jahrgangID where fj.faecherID = fachID";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);
                cmd.Parameters.AddWithValue("@fachID", FachID.Text);

                MySqlDataReader reader = cmd.ExecuteReader();

                //Daten in fachtable füllen
                while (reader.Read())
                {
                    string jahrgangID = reader.GetString("id");
                    string jahrgang = reader.GetString("jahrgang");

                    _jahrgaenge.Add(new Jahrgang(jahrgangID, jahrgang));
                }
                reader.Close();
                sqlConnection.Close();
            }
            return _jahrgaenge;
        }
    }

Der erkennt nicht den Verweis auf die Textbox "FachID" aus der XAML Datei. Daher sagt er mir:

Fehlermeldung:
Der name "FachID" ist im aktuellen Kontext nicht vorhanden.

Ich wollte nicht zu viel Code posten. Sollte etwas fehlen, reiche ich es gerne nach.

Vielen lieben Dank und einen schönen Sonntag noch!
Grüße
Sascha

05.05.2021 - 10:54 Uhr

Ich hoffe, ich gehe euch nicht all zu sehr auf den Sack. Nach und nach verstehe ich es so langsam.

Die if Anweisung ist eine Möglichkeit, ich habe mir jetzt das "gegen Null" prüfen angeschaut.

Dazu habe ich folgende Methode erstellt:


public bool IsNullOrEmptyWertAusWPF(string wertAusWPF)
        {
            bool isempty;

            isempty =  wertAusWPF == null || wertAusWPF == string.Empty;
            
            return isempty;
        }

Wenn ich jetzt 2 verschiedene Typen habe, einmal int und einmal string, müsste ich die Methode genau danach ausrichten? Sprich 2 Methoden anlegen?

Das ganze im Event mit eingefügt:


private void BtnUvEintrag_Click(object sender, RoutedEventArgs e)
        {
            using (MySqlConnection connection = GetConnection())
            {
                
                    bool IsNullOrEmptyFach = IsNullOrEmptyWertAusWPF((string)listFach.SelectedValue);
                    bool IsNullOrEmptyJahrgang = IsNullOrEmptyWertAusWPF((string)listJahrgang.SelectedValue);
                    bool isValidPassword = IsValidPassword(connection, listFach.SelectedValue, Passwort.Text);

                    if (isValidPassword && IsNullOrEmptyFach && IsNullOrEmptyJahrgang)
                    {
                        MessageBox.Show("Das Unterrichtsvorhaben wurde erfolgreich angelegt.");
                    }
                    else
                    {
                        MessageBox.Show("Folgende Angaben müssen vorher gemacht werden:\n- Fach\n- Jahrgang\n- Passwort");
                    }
            }
        }

Der Fehler kommt, da du mit "(int)listFach.SelectedValue" eine Umwandlung des ausgewählten Wert zu int forcierst.

Auch, wenn es doof klingt, hat mir Studio gesagt, ich soll (int) eintragen da ein Objekt nicht in int konvertiert werden kann.
Als alternativ Vorschlag kam folgendes:


throw new NotImplementedException();

Wenn ich richtig verstehe, wird die Meldung damit nur unterdrückt?

05.05.2021 - 09:27 Uhr

Ok, das mit den Breakpoints habe ich verstanden und ist eine super Hilfe. Ich wusste nicht das man so etwas in Studio einstellen kann.

Ich glaube, ich habe erneut einen Gedankenfehler.

Ich habe aktuell ein Problem mit folgender Zeile:


bool isValidPassword = IsValidPassword(connection, (int)listFach.SelectedValue, Passwort.Text);

Wenn ich kein Fach angebe, schmeißt er mir einen Fehler aus.Klar, enthält ja keinen Wert.

Fehlermeldung:
System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

System.Windows.Controls.Primitives.Selector.SelectedValue.get hat null zurückgegeben.

Ich würde, mit meinem Wissensstand daher gehen und eine if Abfrage vorher machen, um zu prüfen, ob die Zeile ausgefüllt ist.


private void BtnUvEintrag_Click(object sender, RoutedEventArgs e)
        {
            using (MySqlConnection connection = GetConnection())
            {
                if (listFach.SelectedValue != null && listJahrgang.SelectedValue != null) 
                {

                    bool isValidPassword = IsValidPassword(connection, (int)listFach.SelectedValue, Passwort.Text);

                    if (isValidPassword)
                    {
                        MessageBox.Show("Das Unterrichtsvorhaben wurde erfolgreich angelegt.");
                    }
                    else
                    {
                        MessageBox.Show("Es wurde ein falsches Passwort angegeben!");
                    }

                }
                else
                {
                    MessageBox.Show("Folgende Angaben müssen vorher gemacht werden:\n- Fach\n- Jahrgang\n- Passwort");
                }

                
            }
        }

Da gibt es mit Sicherheit auch einen anderen Weg, oder?
Auch wieder in eine separate Funktion auslagern?

05.05.2021 - 08:35 Uhr

Guten Morgen zusammen,
der Code sieht wirklich übersichtlicher aus. Ich werde es mir ab jetzt vornehmen und alles überarbeiten.

@Abt, ich habe dein Beispiel gerade übernommen und abgeändert. Bevor ich in die Datenbank speichere gebe ich in der if Anweisung erst einmal eine MessageBox aus.

Was folgendes passiert, wenn ich kein Fach auswähle, bricht das Script einfach ab. Ich würde jetzt einfach eine if Anweisung zur Überprüfung machen (wie im Ursprungsscript von mir).

Jetzt würde mich folgender Satz von dscNRW interessieren:

Hast du denn mal Breakpoints gesetzt und geprüft ob listFach.SelectedValue != null && listJahrgang.SelectedValue != null wirklich true ist?

Überprüfe ich nicht mit der Abfrage ob es true ist?

Liebe Grüße und vielen lieben Dank!
Sascha

04.05.2021 - 18:43 Uhr

Ich übergebe die FachID an die Tabelle (wurde vorher in einer ListBox ausgewählt).
Dadurch suche ich das richtige Passwort raus (Die Passwörter sind nicht an Benutzer sondern an die Fächer gebunden) und vergleiche anschließend
das vom Benutzer eingegebene Passwort mit dem Passwort aus der Datenbank (die entsprechende if).


if (listFach.SelectedValue != null && listJahrgang.SelectedValue != null && Passwort.Text == passDB)

Using habe ich bisher immer genutzt. Ich wusste nur nicht, dass ich die verschachteln kann. Dennoch scheint es (bei mir) nicht ganz zu funktionieren.
Ich verstehe den eigentlichen Aufbau bis jetzt noch nicht.

04.05.2021 - 16:36 Uhr

Also zunächst muss man Dich darauf hinweisen, dass das, was Du hier machst, in der EU verboten ist sofern Du das nicht für Dich privat oder als Übung einsetzt.

Das Passwort wird später wieder verschlüsselt. Grundsätzlich bastel ich das Script zur zum Lernen.
Deine Links schaue ich mir weiterhin an. Ich möchte gerne alle Funktionen erst einmal fertigstellen.
Anschließend, den Hinweis hattest du mir schon einmal gegeben, werde ich alles in die "Drei-Schichten-Architektur" umwandeln. Dazu wollte ich das jetzige erst einmal verstehen.
Zusätzlich muss ich mir noch DataBindings anschauen.

Vielen lieben Dank!

04.05.2021 - 14:39 Uhr

Verwendetes Datenbanksystem: MySQL/MariaDB

Hallo zusammen, ich habe erneut ein Problem bei einer Abfrage.
Ich wusste nicht genau wie ich mein Problem im Title beschreiben sollte. Ich hoffe der ist ok so.

Im ersten Teil lese ich ein Passwort aus und vergleiche es mit dem eingegebenen Passwort (Das Eingabefeld ist eine TextBox, wird aber noch geändert. Ist nur zum testen).

Wenn der Vergleich zutrifft (Bis hier hin funktioniert es) führt er den Teil unter "try" aus. Allerdings macht er keinen DB Eintrag. Jemand einen Tipp wie ich an mögliche Fehlerquellen komme oder sieht auf anhieb was falsch ist? (Bin Anfänger und das ganze ist zum testen)


private void BtnUvEintrag_Click(object sender, RoutedEventArgs e)
        {
            //Passwort auslesen
            MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter();
            MySqlCommand cmd;
            MySqlDataReader reader;

            cmd = new MySqlCommand("select passwort from passwort where fachID = @fachID", sqlConnection);
            sqlConnection.Open();
            cmd.Parameters.AddWithValue("@fachID", listFach.SelectedValue);
            cmd.Parameters.AddWithValue("@uvInsert", sendUvorhaben.Text);
            cmd.Parameters.AddWithValue("@jahrgangID", listJahrgang.SelectedValue);

            reader = cmd.ExecuteReader();
            reader.Read();

            var passDB = reader["passwort"].ToString();

            if (listFach.SelectedValue != null && listJahrgang.SelectedValue != null && Passwort.Text == passDB)
            {
                
                try
                {
                    cmd = new MySqlCommand("insert into uvorhaben (uvorhaben) value (@uvInsert); insert into faecherJahrgangUvorhaben (fachID, jahrgangID, uvorhabenID) value (@fachID, @jahrgangID, LAST_INSERT_ID())", sqlConnection);
                    MessageBox.Show("Unterrichtsvorhaben wurde gespeichert.");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    if (sqlConnection != null) sqlConnection.Close();
                }

            }
            else
            {
                MessageBox.Show("Das Fach und der Jahrgang muss ausgewählt sein.\nEventuell ist auch das Passwort falsch");
            }
        }

Vielen Dank für eure Hilfe! Ich bin sehr Dankbar dafür!
Liebe Grüße
Sascha

03.05.2021 - 16:45 Uhr

Verwendetes Datenbanksystem: <MySql (MariaDB)>

Edit: Das Problem hat sich gerade von selbst gelöst.
Die Lösung habe ich unten gepostet, falls jemand das gleiche Problem hat.

Hallo zusammen, ich möchte in zwei verschiedenen Tabellen Daten schreiben.
Das Problem dabei ist, in die zweite Tabelle soll die ID der ersten Tabelle mit geschrieben werden. Die ID wird in dem Moment allerdings erst automatisch (auto_increment) eingetragen.

Gibt es eine Möglichkeit diese direkt mit zu übergeben?


string query = "insert into uvorhaben (uvorhaben) value (@uvInsert) insert into faecherJahrgangUvorhaben (fachID, jahrgangID, uvorhabenID) value (@fachID, @jahrgangID, ID DIE ZU BEGINN AUTOMATISCH ANGELEGT WIRD";

Lösung:


string query = "insert into uvorhaben (uvorhaben) value (@uvInsert); insert into faecherJahrgangUvorhaben (uvorhabenID, fachID, jahrgangID) value (LAST_INSERT_ID(),@fachID, @jahrgangID)";

Vielen lieben Dank!
Grüße
Sascha

26.04.2021 - 13:11 Uhr

Oh, entschuldige bitte. Ich dachte, so bleibt es übersichtlicher.

Hier der Code der MainWondow.xaml.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using MySql.Data.MySqlClient;
using System.Data.Common;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System.Diagnostics;
using System.IO;
using PdfSharp.Pdf.IO;
using System.Collections.Specialized;

namespace HLSFoerderPlaner
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    /// 
    
   
    public partial class MainWindow : Window
    {
        public MySqlConnection sqlConnection;
        public List list;

        
        public MainWindow()
        {
            InitializeComponent();

            logo.Source = new BitmapImage(new Uri(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "images\\logo.png")));
            Uri iconUri = new Uri(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "images\\favicon.ico"));
            this.Icon = BitmapFrame.Create(iconUri);

            // Erstellung des ConnectionStrings
            string server = "";
            string database = "";
            string uid = "";
            string password = "";
            string connectionString; 
            connectionString = "SERVER=" + server + ";" + "DATABASE=" +
            database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";

            sqlConnection = new MySqlConnection(connectionString);
            
            //Ausgabe der Liste - Fach
            ShowFach();
            
        }

        public void ShowFach()
        {
            try
            {
                //Daten aus der Tabelle lesen
                string query = "select * from faecher order by fach asc";
              
                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    sqlConnection.Open();
                    //Daten in fachtable füllen
                   
                    DataTable fachTable = new DataTable();
                    mysqlDataAdapter.Fill(fachTable);

                    listFach.DisplayMemberPath = "fach";
                    listFach.SelectedValuePath = "id";
                    
                    listFach.ItemsSource = fachTable.DefaultView;

                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

        public void ShowJahrgang()
        {
            try
            {
                
                //Daten aus der Tabelle lesen
                string query = "select * from jahrgang a inner join faecherJahrgang fj on a.id = fj.jahrgangID where fj.faecherID = @fachID";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    cmd.Parameters.AddWithValue("@fachID", listFach.SelectedValue);

                    DataTable jahrgangTable = new DataTable();
                    mysqlDataAdapter.Fill(jahrgangTable);

                    listJahrgang.DisplayMemberPath = "jahrgang";
                    listJahrgang.SelectedValuePath = "id";
                    listJahrgang.ItemsSource = jahrgangTable.DefaultView;


                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

        public void ShowUvorhaben()
        {
            try
            {

                //Daten aus der Tabelle lesen
                string query = "select * from uvorhaben a inner join faecherJahrgangUvorhaben fju on a.id = fju.uvorhabenID where fju.fachID = @fachID AND fju.jahrgangID = @jahrID order by uvorhaben asc";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    cmd.Parameters.AddWithValue("@fachID", listFach.SelectedValue);
                    cmd.Parameters.AddWithValue("@jahrID", listJahrgang.SelectedValue);

                    DataTable uvorhabenTable = new DataTable();
                    mysqlDataAdapter.Fill(uvorhabenTable);

                    listUvorhaben.DisplayMemberPath = "uvorhaben";
                    listUvorhaben.SelectedValuePath = "id";
                    listUvorhaben.ItemsSource = uvorhabenTable.DefaultView;

                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

        public void ShowKompetenzen()
        {
            try
            {

                //Daten aus der Tabelle lesen
                string query = "select * from kompetenzen a inner join uvKomp uvk on a.id = uvk.kompID where uvk.jahrgangID = @jahrID AND uvk.uvorhabenID = @uvorhabenID order by kompetenz asc";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    cmd.Parameters.AddWithValue("@uvorhabenID", listUvorhaben.SelectedValue);
                    cmd.Parameters.AddWithValue("@jahrID", listJahrgang.SelectedValue);

                    DataTable kompetenzTable = new DataTable();
                    mysqlDataAdapter.Fill(kompetenzTable);

                    listKompetenz.SelectionMode = SelectionMode.Multiple;
                    listKompetenz.DisplayMemberPath = "kompetenz";
                    listKompetenz.SelectedValuePath = "id";
                    listKompetenz.ItemsSource = kompetenzTable.DefaultView;


                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

        public void ShowKompetenzErwartungen()
        {
            try
            {

                //Daten aus der Tabelle lesen
                string query = "select * from kompErwartungen a inner join uvJahrErwartungen uje on a.id = uje.kompErwartungenID where uje.jahrgangID = @jahrID AND uje.uvID = @uvID order by kompErwartungen asc";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    cmd.Parameters.AddWithValue("@uvID", listUvorhaben.SelectedValue);
                    cmd.Parameters.AddWithValue("@jahrID", listJahrgang.SelectedValue);

                    DataTable kompErwartungenTable = new DataTable();
                    mysqlDataAdapter.Fill(kompErwartungenTable);

                    listFoerder.SelectionMode = SelectionMode.Multiple;
                    listFoerder.DisplayMemberPath = "kompErwartungen";
                    listFoerder.SelectedValuePath = "id";
                    listFoerder.ItemsSource = kompErwartungenTable.DefaultView;


                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

        private void ListFach_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowJahrgang();
        }

        private void ListJahrgang_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowUvorhaben();
        }

        private void ListKompetenz_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowKompetenzen();
            ShowKompetenzErwartungen();
        }

        private void PdfErstellen_Click(object sender, RoutedEventArgs e)
        {
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            PdfDocument document = new PdfDocument();
            PdfPage page = document.AddPage();
            page.Size = PdfSharp.PageSize.A4;
            XGraphics gfx = XGraphics.FromPdfPage(page);


            XFont font = new XFont("Bell MT", 12);
            XFont fontfett = new XFont("Bell MT", 12, XFontStyle.Bold);
            XFont uschrift = new XFont("Bell MT", 18, XFontStyle.Bold);
            

            //Hintergrund- Overlay
            gfx.DrawImage(XImage.FromFile(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "images\\overlay.png")), 0, 0);

            //Überschrift
            gfx.DrawString("Individueller Förderplan von " + name.Text, uschrift, XBrushes.Black, new XRect(40, 150, page.Width, page.Height), XStringFormats.TopLeft);


            var FachItem = (listFach.SelectedItem as DataRowView)["fach"].ToString();
            var UvItem = (listUvorhaben.SelectedItem as DataRowView)["uvorhaben"].ToString();

            
            var kompItems = (listKompetenz.SelectedItem as DataRowView)["kompetenz"].ToString();
            var FoerderItem = (listFoerder.SelectedItem as DataRowView)["kompErwartungen"].ToString();

            gfx.DrawString("Fach: ", fontfett, XBrushes.Black, new XRect(40, 200, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(FachItem, font, XBrushes.Black, new XRect(75, 200, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString("Unterrichtsvorhaben: ", fontfett, XBrushes.Black, new XRect(40, 215, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(UvItem, font, XBrushes.Black, new XRect(155, 215, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString("Lernziel:", fontfett, XBrushes.Black, new XRect(40, 230, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(name.Text + " wird in dieser Unterrichtseinheit ", font, XBrushes.Black, new XRect(40, 245, page.Width, page.Height), XStringFormats.TopLeft);
            
            if (zielgleich.IsChecked == true)
            {
                gfx.DrawString("zielgleich unterrichtet und dabei die nachfolgend aufgeführten Kompetenzen erwerben.", font, XBrushes.Black, new XRect(40, 260, page.Width, page.Height), XStringFormats.TopLeft);
            }
            if (zieldifferent.IsChecked == true)
            {
                gfx.DrawString("zieldifferent unterrichtet und dabei die nachfolgend aufgeführten Kompetenzen erwerben.", font, XBrushes.Black, new XRect(40, 260, page.Width, page.Height), XStringFormats.TopLeft);
            }
            if (alternativLZ.IsChecked == true)
            {
                gfx.DrawString("ein alternatives Lernziel verfolgen und damit die nachfolgend aufgeführten Kompetenzen erwerben.", font, XBrushes.Black, new XRect(40, 260, page.Width, page.Height), XStringFormats.TopLeft);
            }

            gfx.DrawString("Kompetenzerwartungen", fontfett, XBrushes.Black, new XRect(40, 290, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(name.Text + " kennt/kann ... ", font, XBrushes.Black, new XRect(40, 305, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(kompItems, font, XBrushes.Black, new XRect(40, 320, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString("Fördermaßnahmen", fontfett, XBrushes.Black, new XRect(40, 335, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(name.Text + " ... ", font, XBrushes.Black, new XRect(40, 350, page.Width, page.Height), XStringFormats.TopLeft);
            gfx.DrawString(FoerderItem, font, XBrushes.Black, new XRect(40, 365, page.Width, page.Height), XStringFormats.TopLeft);

            string filename = System.IO.Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop), this.name.Text + "-Förderplan.pdf");
            document.Save(filename);
            MessageBox.Show("Die PDF wurde auf dem Desktop gespeichert.");
        }     
}
}


Und hier die entsprechende XAML


<Window x:Class="HLSFoerderPlaner.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:HLSFoerderPlaner"
        mc:Ignorable="d"
        Title="Förderplaner" 
        Height="863" 
        Width="1000"
       >
    <Window.Effect>
        <DropShadowEffect/>
    </Window.Effect>
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,10,2,-12" Width="980" Height="834">
        <Label Content="Förderplaner" Margin="333,10,330,748" FontSize="48" FontWeight="Bold" FontStyle="Italic" HorizontalAlignment="Center" Width="317"/>

        <TextBox Name ="name" HorizontalAlignment="Left" Height="23" Margin="288,119,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" RenderTransformOrigin="-0.003,0.669"/>
        <Label Content="Name:" HorizontalAlignment="Left" Margin="222,116,0,0" VerticalAlignment="Top"/>

        <Label Content="Zielkontrolle:" HorizontalAlignment="Left" Margin="426,100,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="lzk" Content="LZK" HorizontalAlignment="Left" Margin="508,107,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="koratest" Content="Kompetenzrastertest(s)" HorizontalAlignment="Left" Margin="508,127,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="klabasis" Content="Klassenarbeit (Basis und Einstieg)" HorizontalAlignment="Left" Margin="508,147,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="klaaufstieg" Content="Klassenarbeit (Einstieg und Aufstieg)" HorizontalAlignment="Left" Margin="508,167,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="alternachweis" Content="Alternativer Leistungsnachweis" HorizontalAlignment="Left" Margin="508,187,0,0" VerticalAlignment="Top"/>

        <Label Content="Zeitraum: " HorizontalAlignment="Left" Margin="690,105,0,0" VerticalAlignment="Top"/>
        <Label Content="Von: " HorizontalAlignment="Left" Margin="758,105,0,0" VerticalAlignment="Top"/>
        <Label Content="Bis: " HorizontalAlignment="Left" Margin="764,141,0,0" VerticalAlignment="Top"/>
        <DatePicker x:Name="Von" HorizontalAlignment="Left" Margin="796,107,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.14,0.656" />
        <DatePicker x:Name="Bis" HorizontalAlignment="Left" Margin="796,142,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.69,1.167"/>

        <CheckBox x:Name="zielgleich" Content="SuS wird zielgleich unterrichtet und dabei die nachfolgend aufgeführten Kompetenzen erwerben." HorizontalAlignment="Left" Margin="31,238,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="zieldifferent" Content="SuS wird zieldifferent unterrichtet und dabei die nachfolgend aufgeführten Kompetenzen erwerben." HorizontalAlignment="Left" Margin="31,258,0,0" VerticalAlignment="Top"/>
        <CheckBox x:Name="alternativLZ" Content="SuS wird ein alternatives Lernziel verfolgen und damit die nachfolgend aufgeführten Kompetenzen erwerben." HorizontalAlignment="Left" Margin="31,278,0,0" VerticalAlignment="Top"/>

        <TextBox Name ="schuljahr" HorizontalAlignment="Left" Height="23" Margin="288,156,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" RenderTransformOrigin="-0.003,0.669"/>
        <Label Content="Schuljahr:" HorizontalAlignment="Left" Margin="222,156,0,0" VerticalAlignment="Top"/>

        <Label Content="Fach:" HorizontalAlignment="Left" Margin="31,310,0,0" VerticalAlignment="Top"/>
        <Label Content="Jahrgang" HorizontalAlignment="Left" Margin="197,310,0,0" VerticalAlignment="Top"/>
        <Label Content="Unterrichtsvorhaben" HorizontalAlignment="Left" Margin="274,310,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.517,-0.346"/>

        <ListBox Name ="listFach" HorizontalAlignment="Left" SelectionChanged="ListFach_SelectionChanged" Height="175" Margin="31,336,0,0" VerticalAlignment="Top" Width="150"/>
        <ListBox Name ="listJahrgang" HorizontalAlignment="Left" SelectionChanged="ListJahrgang_SelectionChanged" Height="175" Margin="202,336,0,0" VerticalAlignment="Top" Width="50"/>
        <ListBox Name ="listUvorhaben" HorizontalAlignment="Left" SelectionChanged="ListKompetenz_SelectionChanged" Height="175" Margin="274,336,0,0" VerticalAlignment="Top" Width="200"/>

        <Label Content="Kompetenzerwartungen:" HorizontalAlignment="Left" Margin="27,523,0,0" VerticalAlignment="Top"/>
        <ListBox Name ="listKompetenz" HorizontalAlignment="Left" Height="200" Margin="27,549,0,0" VerticalAlignment="Top" Width="441"/>
        <Image Name="logo" HorizontalAlignment="Left" Height="213" Margin="28,6,0,0" VerticalAlignment="Top" Width="178" />


        <Label Content="Fördermaßnahmen:" HorizontalAlignment="Left" Margin="496,523,0,0" VerticalAlignment="Top"/>
        <ListBox x:Name ="listFoerder" HorizontalAlignment="Left" Height="200" Margin="496,549,0,0" VerticalAlignment="Top" Width="441"/>
        <Button Name="pdfErstellen" Content="PDF erstellen" HorizontalAlignment="Left" Margin="803,763,0,0" VerticalAlignment="Top" Width="135" Height="35" Click="PdfErstellen_Click"/>



    </Grid>
</Window>


26.04.2021 - 13:07 Uhr

In erster Linie vielen vielen Dank, das ihr zwei euch die Zeit nehmt.

Den Hinweis mit der Datenbank nehme ich gerne an. Auch, wenn Abt relativ recht hat, das mein Wissensstand nicht besonders groß ist.
Das Projekt ist zum Lernen da. Daher nehme ich jeden Tipp und Hinweis an.
Der jetzige Wissensstand beruht auf einem Udemy Kurs. Irgendwie muss man ja anfangen 😁

Ich bin jetzt mal so frech und stelle den Code per Pastebin online. An welcher Stelle sollte ich die Datenbank öffnen/schließen?

MainWindow.xaml.cs
Edit von Abt: Link entfernt

MainWindow.xaml
Edit von Abt: Link entfernt
DataBindings werde ich mir anschauen. Hier bin ich, wie gesagt, anhand eines Udemy Kurses heran gegangen. Daher habe ich mich auf den Aufbau ein wenig Verlassen.

Zu meinem Ursprünglichen Problem:

Dann musst Du mit SelectedItems (also Plural, nicht das Single-Item) arbeiten.

Das hatte ich probiert. Allerdings gab es ebenfalls nur den genannten Fehler als Ausgabe.

Jetzt habe ich öfters gelesen, dass ich eventuell eine for-Schleife nutzen soll. Wäre das eine Möglichkeit? (als Übergangslösung)

Vielen lieben Dank nochmals!
Liebe Grüße
Sascha

25.04.2021 - 21:45 Uhr

Ich versuche mal die entsprechenden Code Teile zu kopieren.
Das hier ist die Funktion, die die Werte an die ListBox sendet:


public void ShowKompetenzen()
        {
            try
            {

                //Daten aus der Tabelle lesen
                string query = "select * from kompetenzen a inner join uvKomp uvk on a.id = uvk.kompID where uvk.jahrgangID = @jahrID AND uvk.uvorhabenID = @uvorhabenID order by kompetenz asc";

                MySqlCommand cmd = new MySqlCommand(query, sqlConnection);

                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(cmd);

                using (mysqlDataAdapter)
                {
                    cmd.Parameters.AddWithValue("@uvorhabenID", listUvorhaben.SelectedValue);
                    cmd.Parameters.AddWithValue("@jahrID", listJahrgang.SelectedValue);

                    DataTable kompetenzTable = new DataTable();
                    mysqlDataAdapter.Fill(kompetenzTable);

                    listKompetenz.SelectionMode = SelectionMode.Multiple;
                    listKompetenz.DisplayMemberPath = "kompetenz";
                    listKompetenz.SelectedValuePath = "id";
                    listKompetenz.ItemsSource = kompetenzTable.DefaultView;


                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                sqlConnection.Close();
            }
        }

Das hier ist die entsprechende ListBox in XAML


<ListBox Name ="listKompetenz" HorizontalAlignment="Left" Height="200" Margin="27,549,0,0" VerticalAlignment="Top" Width="441" SelectionChanged="listKompetenz_SelectionChanged_1"/>

Ich habe einen Button eingefügt. Wenn er betätigt wird, wird die PDF (mit PDFSharp) erstellt.

Das ist ein Teilauszug aus dem Bereich:


var kompItems = (listKompetenz.SelectedItem as DataRowView)["kompetenz"].ToString();

gfx.DrawString(kompItems, font, XBrushes.Black, new XRect(40, 320, page.Width, page.Height), XStringFormats.TopLeft);

Das Thema DataBinding schaue ich mir mal an. Ist nur recht schwierig, als Anfänger, die richtigen Seiten zu finden.

Vielen Dank für den Tipp!
Grüße
Sascha

25.04.2021 - 20:10 Uhr

Hallo und einen schönen Sonntag zusammen,
ich bin neu hier im Forum sowie ein recht blutiger Anfänger was C# angeht.
Ich sitze gerade vor einem Problem.
Ich möchten Daten aus einer ListBox in eine PDF schreiben.
Die ListBoxen werden von mir mit Daten aus einer Datenbank befüllt:


listKompetenz.DisplayMemberPath = "kompetenz";
listKompetenz.SelectedValuePath = "id";
listKompetenz.ItemsSource = kompetenzTable.DefaultView;

Jetzt möchte ich, wenn eins der Elemente ausgewählt wurde, das Element in eine PDF (mit PDFSharp) schreiben.
Statt den ausgewählten Text wurde:

Fehlermeldung:
System.Data.DataRowView

ausgegeben.

Also habe ich folgendes gemacht:


var FachItem = (listFach.SelectedItem as DataRowView)["fach"].ToString();

Jetzt wird mir der richtige Text ausgegeben.
Leider habe ich eine Liste, bei der eine Mehrfachauswahl gemacht werden kann. Dort funktioniert es leider nicht.
Wenn ich mit Arrays oder Listen arbeite, meldet er, dass DataRowView nicht als String konvertiert werden kann.
Hat jemand ein Tipp für mich?
Vielen Dank im voraus!
Grüße
Sascha