Autor Beitrag
shacknet
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 01.07.08 00:48 
Hallo,
ich schon wieder.

Also nachdem mein Problemchen mit meinem Timer gelöst ist, habe ich eine neue Frage.
Wie man aus dem Titel entnehmen kann will ich einige Textboxen und Label zur Laufzeit erstellen.

Ich habe bisher folgendes:

Ich stelle eine Abfrage an eine MySQL Datenbank und frage alle Datensätze ab die vorhanden sind.
Diese Datensätze, es handelt sich um Spenden, werden in Textboxen geladen, damit ich sie dort nötigenfalls bearbeiten kann.
Zurzeit, zu Testzwecken, ist nur ein Datensatz vorhanden also brauche ich auch nur einmal die 11 Textboxen und das eine Label.
Wenn ich jetzt an die Online Datenbank gehe, auf welche ca 15 Datensätze sind habe ich das Problem, dass ich zu wenig boxen habe. Und da die Datensätze variieren (zwischen 10 und 40, zur Zeit, kann mehr werden) ist es sehr schlecht über visible on|off zu arbeiten.

Naja hier mal mein bisheriger Code:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            MySqlConnection dataConnection = new MySqlConnection();

            try
            {
                
                dataConnection.ConnectionString = ("Network Address=mein.super.host;" +
                                                                "Initial Catalog='dietolledb';" +
                                                                "Persist Security Info=no;" +
                                                                "User Name='dertolleuser';" +
                                                                "Password='dastollepw'");
                dataConnection.Open();

                MySqlCommand dataCommand = new MySqlCommand();
                dataCommand.Connection = dataConnection;
                dataCommand.CommandText = ("SELECT * FROM SpendenVerwaltung");

                MySqlDataReader dataReader = dataCommand.ExecuteReader();

                while (dataReader.Read())
                {
                    string member = dataReader.GetString(1);
                    string montag = dataReader.GetString(2);
                    string dienstag = dataReader.GetString(3);
                    string mittwoch = dataReader.GetString(4);
                    string donnerstag = dataReader.GetString(5);
                    string freitag = dataReader.GetString(6);
                    string samstag = dataReader.GetString(7);
                    string sonntag = dataReader.GetString(8);
                    string wocheGesamt = dataReader.GetString(9);
                    string letzterMonat = dataReader.GetString(10);
                    string Gesamt = dataReader.GetString(11);

                    this.lblUser.Content = member;
                    this.txtMontag.Text = montag;
                    this.txtDienstag.Text = dienstag;
                    this.txtMittwoch.Text = mittwoch;
                    this.txtDonnerstag.Text = donnerstag;
                    this.txtFreitag.Text = freitag;
                    this.txtSamstag.Text = samstag;
                    this.txtSonntag.Text = sonntag;
                    this.txtWoche.Text = wocheGesamt;
                    this.txtLastMonth.Text = letzterMonat;
                    this.txtGesamt.Text = Gesamt;

                    
                }
                dataReader.Close();
            }
            catch(MySqlException ex)
            {
                MessageBox.Show("Fehler beim Zugriff auf die Datenbank", ex.Message);
            }
            finally
            {
                dataConnection.Close();
            }
            
        }

Den "dataReader.GetString(0)" gibt es nicht, da die erste Spalte die einmalige ID ist, die brauch ich nicht abfragen...
So, nun muss ich ja dann in dem "while"-blog die Textbox variabel erstellen. Also wenns 10 Datensätze sind 10 mal die Felder. und bei 20 halt 20 mal die Felder.
Wie bewerkstellige ich das? Mit allen Werten. (Breite, Höhe, Alignments, name)
Wichtig ist vorallem das mit dem Namen. Ich habe da schon an eine Variabel gedacht die automatisch hochgezählt wird.
Ich brauche den Namen, um die Werte "Woche", "Gesamt" und "LetzterMonat" zu berrechnen.
Und da muss ich dann ja auch an die Variablen Namen dran. Ist das alles Möglich??

Ich würde mich über Hilfe freuen...

Shacknet
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Di 01.07.08 09:31 
Hallo,

schau einmal in die Designer.cs rein: Genauso wie es der Designer macht, kannst Du auch manuell zur Laufzeit Controls erstellen. Du musst Dir lediglich Gedanken darüber machen, wie Du die Controls (bei Dir: TextBoxen) benennen willst; dazu bietet sich eine Kombination von Datensatz-Inhalt und Feldinhalt an.

Du solltest aber über das Konzept nochmal nachdenken. Es ist meistens kein schönes Verfahren, wenn eine Vielzahl gleichartiger Elemente zur Laufzeit erzeugt werden. Alternativen sind:
* eine Sammlung von Controls sowie eine Auswahlliste, die die Controls konkret mit Inhalt füllt;
* ein UserControl mit allen TextBoxen, für jeden Datensatz wird ein UserControl erstellt

Jürgen
shacknet Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 01.07.08 09:37 
Hallo JüTho,

danke für die antwort.
Ich glaube die Idee mit dem UserControl ist gar nicht mal so übel.
Ich überlege gerade an eine Art Navigationsleiste um dann durch die Datensätze zu scrollen. Bzw auch SuFu und die dann Implementieren, das ist vermutlich sauberer zu Programmieren.
Ich schau mir das mal an.

Ich melde mich dann wenn noch was unklar ist.
Ich muss ersmal noch arbeiten. Also kann ich esrt ab 15 uhr tüfteln.
=)

shacknet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.07.08 10:42 
Wenn man schon WPF benutzt, sollte man auch dessen Möglichkeiten nutzen. Mir käme es im Leben nicht in den Sinn, bei sowas die Textboxen per Hand zu erstellen.

Erstell Dir eine Klasse:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
public class Spende {
    public string Member {get; set;}
    public string Montag {get; set;}
    /*...*/
}


Dann erstellst Du Dir eine ObservableCollection<Spende> als Feld Deiner Window1-Klasse und füllst die im Window1-Loaded-Ereignis:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
partial class Window1 {
        ObservableCollection<Spende> spenden;

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
                /* ... das ganze Zeug davor ... */

                spenden = new ObservableCollection<Spende>();
                while (dataReader.Read())
                {
                    spenden.Add(new Spende() {
                        Member = dataReader.GetString(1),
                        Montag = dataReader.GetString(2)
                        /* ... */
                    });                 
                }
                dataReader.Close();
                lbSpenden.ItemsSource = spenden;
            }
            catch(MySqlException ex)
            {
                MessageBox.Show("Fehler beim Zugriff auf die Datenbank", ex.Message);
            }
            finally
            {
                dataConnection.Close();
            }
            
        }
}


Deine Textboxen erstellst Du in einer Listbox namens "lbSpenden" per DataTemplate:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
        <ListBox Name="lbSpenden">
            <ListBox .ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=Member}" Grid.Column="0" />
                        <TextBox Text="{Binding Path=Montag}" Grid.Column="1" />
                    </Grid>
                </DataTemplate>
            </ListBox .ItemTemplate>
        </ListBox>


So, das schöne an der Sache ist, dass die Listbox sofort "mitbekommt", sobald Du eine Spende aus der Liste entfernst oder eine hinzufügst. Außerdem werden Änderungen in der Textbox direkt in die Liste übernommen, ohne dass Du noch Code dafür schreiben musst. Du musst hinterher nur noch dafür sorgen, dass die Änderungen auch in der Datenbank landen. Da würde ich in der Spende-Klasse ein Feld IsChanged einführen, welches in jedem Setter auf true gesetzt wird.

Ich glaube, für den Anfang war es das erstmal :gruebel:

Vielleicht noch ein gut gemeinter Rat: Versuche nicht, die Dinge in WPF so zu machen, wie Du es in WinForms gemacht hast. Versuche, zu überleben, welche Möglichkeiten WPF Dir bietet. WPF wird Dir noch genug Gelegenheiten geben, Dich drüber zu ärgern und Dinge umständlich machne zu müssen, da solltest Du jede Gelegenheit nutzen, Dir Arbeit zu ersparen ;-)

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 01.07.08 10:49 
Christian, du sprichst mir aus der Seele ;) .
Das WPF-DataGrid lässt zwar noch auf sich warten, aber bis es so weit ist, dürfte die ListView das ähnlichste Control sein. Siehe auch msdn.microsoft.com/e...ibrary/ms745183.aspx (oder natürlich im lokalen SDK: "How to: Create a ListView with Editable Cells". Oder gleich in den WPF Samples: "\Controls\ListViewEditable").
shacknet Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 01.07.08 18:39 
Zu der ObservableCollection
Ich finde die bei mir im Namespace nicht.
Habe dann mal in der MSDN geschaut. Ich nutze ja XAML, sorry das ich es vergaß zu erwähnen.
Aber laut MSDN gibt es das nicht bei XAML.

Kann es daran liegen?
Sorry das ich mich noch nciht so auskenne, bin gearde auf Umsteigen von Visual Basic .NET auf Visual C#...

Shacknet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.07.08 19:30 
XAML ist nur eine Beschreibungssprache, daher kann es etwas "bei XAML" auch nicht wirklich geben. Es kann höchstens sein, dass man eine Klasse in XAML nicht instanzieren / verwenden kann. Aber das musst Du bei der ObservableCollection ja auch nicht.

Und wenn ich "ObservableCollection" in den Index der Doku eintippe, bekomme ich direkt den passenden Eintrag. Der Namsepace ist "System.Collections.ObjectModel" in Assembly WindowsBase.dll.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
shacknet Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 02.07.08 09:03 
Das hbae ich auch eingetippt, dann auf den obersten Link, und dort stand Sinngemäß
"XAML: Ist nicht verfügbar"
Aber vermutlich mal wieder nur ein Missverständnis...

Shacknet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mi 02.07.08 10:51 
Du benutzt die Collection auch nicht in XAML. Dort benutzt Du nur das Binding an die Klasseneigenschaften.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".