Abfragen woher ein Form geöffnet wurde
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.
-
-
-
@TS71M:: So:
VB.NET-Quellcode
- Public Class Form1
- Private dlg2 As Form2
- Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
- Using dlg As New Form2
- dlg.ShowDialog()
- End Using
- End Sub
- Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
- If dlg2 Is Nothing OrElse dlg2.IsDisposed Then
- dlg2 = New Form2
- End If
- If Not dlg2.Visible Then
- dlg2.Show()
- End If
- End Sub
- End Class
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
TS71M schrieb:
Jetzt bräuchte ich allerdings einen Tip, wie ich feststellen kann von welchem Form aus aufgerufen wurde.
(die Gräuseligkeiten hab ich glaub ja schon in deim anneren Thread gesehen und kurz angesprochen, aber du bist nicht drauf eingegangen - wäre auch zuviel geworden)
Aber erklär mal: Warum willst du in Form2 wissen, welches Form1 es geöffnet hat? -
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@ErfinderDesRades: Ich habe in der 2. Form variablen die davon abhängen. Wie sonst soll man das lösen?
(die Gräuseligkeiten hab ich glaub ja schon in deim anneren Thread gesehen und kurz angesprochen, aber du bist nicht drauf eingegangen - wäre auch zuviel geworden)
Ausserdem hatte ich dir darauf geantwortet und es bewusst verworfen, da es total umständlich für die Usereingabe wäre und hässlich aussieht.
Ich denke nicht, dass du anhand der Ausschnitte, die du gesehen hast, beurteilen kannst ob dies grauselig ist oder nicht. Ausserdem hat jeder seine eigene Vorstellung, wie was aussehen soll.
Ich möchte mein 1. Form einfach nicht mit zu vielen Items vollknallen und habe deswegen einige(die nur optional nötig sind) auf ein anderes Form gepackt.
@RodFromGremany: Danke werd ich gleich mal ausprobieren. -
sry - bist du angepisst wg. des Wortes "Gräuseligkeit"? Das ist als humoristische Ausdrucksweise für "verbesserungsbedürftig" gemeint.
Sowas muss man halt iwie benennen können, um helfen zu können, und dir kann auch nur geholfen werden, wenn du es aushälst, dass sowas benannt wird.
@Topic:TS71M schrieb:
Ich habe in der 2. Form variablen die davon abhängen. Wie sonst soll man das lösen?
Mehr soll das Form2 auch gar nicht tun: Eingaben entgegennehmen, und in seinen Variablen aufbewahren.
Nachdem Form2 geschlossen wird, kann Form1 die Variablen auswerten und darauf reagieren. Das wäre saubere Architektur, weil dann Form2 nicht im Form1 herumfuhrwerkelt.
Dass andersherum Form1 in Form2 herumfuhrwerkelt (etwa Default-Werte setzt) ist ok, denn Form1 ist der Owner von Form2 - es hat letzteres ja erstellt.
Am einfachsten ist das lösbar über den Dialog-Pattern, also Form2 öffnet als Dialog, d.h. Form1 ist solange blockiert und wartet, bis Form2 wieder geschlossen ist.
gugge zB DialogResultSample -
TS71M schrieb:
nicht mit zu vielen Items vollknallenFalls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@ErfinderDesRades: Nein ich war nicht angepisst, nur etwas eingeschnappt, da ich wirklich schon viel Zeit in das Projekt investiert habe und es wie ein "Baby" für mich ist. Und du weisst ja: Nur die Babys der Anderen sind hässlich
Also ich hab's jetzt so gelöst und würde gerne eure Meinung hören.
Im aufrufenden Form:
Und im geöffnete Dialog
Ich wollte es eigentlich mit einer Select Abfrage machen, aber irgendwie will er nicht:
Bei:
schreibt er: Relationaler Operator erwartet.
Also gut, dann so
Der =-Operator ist für die Type soundso und blablabla nicht definiert.
Aber bei if Abfrage, kein Problem.
Und es funktioniert... -
TS71M schrieb:
würde gerne eure Meinung hören.
nicht Form2 holt sich die BindingSource aus Form1, sondern Form1 - der Owner - gibt sie in Form2 hinein.
Im aufrufenden Form:
Noch besser - wie gesagt: Form2 nimmt nur Eingaben entgegen - dazu brauchts die BindingSource garnet.
Und das autoInserten ist Aufgabe von Form1, denn die BindingSource ist in Form1 erstellt und wird da benötigt - dann soll sie dort auch befüllt werden, und - wenn sichs irgend vermeiden lässt - nicht woanders.
Hast du dir den Dialog-Sample-Film mal angeguckt? -
TS71M schrieb:
und würde gerne eure Meinung hören.
Mach Dir ein Enum, das Du im Konstruktor übergibst:
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@Rod: nein, das ist Spaghetti-Architektur. Kein Enum, kein Select Case.
Der Aufrufer soll jeweils seinen Job machen, und das SubForm soll auch nur seinen eigenen Job machen - nicht den des Aufrufers.
Keine unnötige Kopplung einbauen, sodass das Subform den Datentyp des Aufrufers kennen muss - den muss es nicht kennen!
Der Aufrufer muss das Subform kennen - sonst kanners ja nicht aufrufen. Aber die Abhängigkeit in Gegenrichtung ist unnötig und schlechte Architektur. -
ErfinderDesRades schrieb:
das ist Spaghetti-Architektur
Das war auch nur ein "Verbesserungsvorschlag" von wegen(Me)
beim Aufruf mitzugeben.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@ ErfinderDesRades Natürlich habe ich mir dein Video angeschaut. Ich will ja was lernen.
Ich würde es auch gerne so
Noch besser - wie gesagt: Form2 nimmt nur Eingaben entgegen - dazu brauchts die BindingSource garnet.
machen, nur wie?
Und vor allem nicht vergessen, dass ich von mehreren Forms auf diesen Dialog zugreifen will.
Also hier habe ich die beiden Subs die Änderungen vornehmen:
VB.NET-Quellcode
- Private Sub ClearFillRow()
- CurrentRw = PlanAutoInsertBindingSource.At(Of AppPlanRow)()
- Select Case MessageBox.Show(Me, "Do you want to clear before?", "Add new", MessageBoxButtons.YesNoCancel)
- Case Windows.Forms.DialogResult.No
- Insert()
- Case Windows.Forms.DialogResult.Yes
- For i = 22 To 74
- CurrentRw(i) = 0
- Next
- Insert()
- Case Windows.Forms.DialogResult.Cancel
- Exit Sub
- End Select
- End Sub
- Private Sub Insert()
- Dim StartWeek As Integer = GetKW(dtpStart.Value)
- Dim EndWeek As Integer = GetKW(dtpEnd.Value)
- Dim StartDate As Date = dtpStart.Value
- Dim CurrentRw = PlanAutoInsertBindingSource.At(Of AppPlanRow)()
- Select Case rbEndsAfter.Checked
- Case True
- Select Case rbDays.Checked
- Case True 'days
- EndWeek = GetKW(dtpStart.Value.AddDays((nudApps.Value - 1) * nudPeriod.Value))
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value / 7)
- CurrentRw(i + 22) = nudRate.Value
- Next
- Case False 'weeks
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value)
- CurrentRw(i + 22) = nudRate.Value
- Next
- End Select
- Case False
- Select Case rbDays.Checked
- Case True 'days
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value / 7)
- CurrentRw(i + 22) = nudRate.Value
- Next
- Case False 'weeks
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value)
- CurrentRw(i + 22) = nudRate.Value
- Next
- End Select
- End Select
- End Sub
Muss ich die dann hier heraus nehmen und in die Main einbauen? Wenn ich dann aber unterschiedliche Mains habe, die darauf zugreifen, muss ich es dann in jedem einbauen? Oh Mann, ich muss vor allem noch viel lernen...
Aber wie rufe ich dies jetzt auf? -
ich könnte es dir auch vorkauen, nur müsstest du vollständigen code einstellen, also Form1, wie es Form2 aufruft, und Form2, wie es in Form1 rumfummelt, oder wie auch immer das derzeit gestaltet ist.
nur so Methoden, ohne zu wissen, wo die drin sind - ist mir zu unbestimmt - hinterher bastel ich was drumrum, was ühaupt nicht passt.
Kriegst du eine Dialog-Kommunikation nach dem Dialog-Pattern hin?
also einfach wie in dem Film den Dialog gebastelt, und wie in dem Film aufgerufen und das Dialogresult ausgewertet, obs Dialogresult.Ok ist oder nicht? -
Ok läuft...
VB.NET-Quellcode
- Private Sub AutoInsert_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgvFertilizer.CellContentClick, dgvFungicide.CellContentClick, dgvHerbicide.CellContentClick, dgvInsecticide.CellContentClick, dgvOther.CellContentClick
- With dgvActual.CurrentRow
- If e.ColumnIndex = .Cells(8).ColumnIndex And .Cells(1).Value IsNot DBNull.Value And .Cells(7).Value IsNot DBNull.Value Then
- fmPlanAutoInsert.ShowDialog()
- If fmPlanAutoInsert.DialogResult = Windows.Forms.DialogResult.OK Then ClearFillRow()
- End If
- End With
- End Sub
- Private Sub ClearFillRow()
- Dim CurrentRw As DataRow = AppPlanBindingSource.At(Of AppPlanRow)()
- Select Case MessageBox.Show(Me, "Do you want to clear before, or just adding?", "Auto Insert", MessageBoxButtons.YesNoCancel)
- Case Windows.Forms.DialogResult.No
- Insert()
- Case Windows.Forms.DialogResult.Yes
- For i = 22 To 74
- CurrentRw(i) = 0
- Next
- Insert()
- Case Windows.Forms.DialogResult.Cancel
- Exit Sub
- End Select
- End Sub
- Private Sub Insert()
- With fmPlanAutoInsert
- Dim StartWeek As Integer = GetKW(.dtpStart.Value)
- Dim EndWeek As Integer = GetKW(.dtpEnd.Value)
- Dim StartDate As Date = .dtpStart.Value
- Dim CurrentRw = AppPlanBindingSource.At(Of AppPlanRow)()
- Select Case .rbEndsAfter.Checked
- Case True
- Select Case .rbDays.Checked
- Case True 'days
- EndWeek = GetKW(.dtpStart.Value.AddDays((.nudApps.Value - 1) * .nudPeriod.Value))
- For i = StartWeek - 1 To EndWeek Step CInt(.nudPeriod.Value / 7)
- CurrentRw(i + 22) = .nudRate.Value
- Next
- Case False 'weeks
- For i = StartWeek - 1 To EndWeek Step CInt(.nudPeriod.Value)
- CurrentRw(i + 22) = .nudRate.Value
- Next
- End Select
- Case False
- Select Case .rbDays.Checked
- Case True 'days
- For i = StartWeek - 1 To EndWeek Step CInt(.nudPeriod.Value / 7)
- CurrentRw(i + 22) = .nudRate.Value
- Next
- Case False 'weeks
- For i = StartWeek - 1 To EndWeek Step CInt(.nudPeriod.Value)
- CurrentRw(i + 22) = .nudRate.Value
- Next
- End Select
- End Select
- End With
- End Sub
Allerdings habe ich jetzt die beiden Subs im Main. Und dies muss ich jetzt in jedes Form einbauen, das auf den Dialog zugreift? Ist das nicht auch redundant? -
Das läuft?
da muss man ja nun 2 Dialoge durchklicken.
Und die Messagebox scheint zu lügen, wenn sie sagt "clear before", denn wenn gecleart wird, dann wird ja nicht mehr befüllt.
Diese Eingaben entgegennehmen: ob clearen oder befüllen, und wenn ja wie - sowas gehört in den Dialog.
Aber ich kann immer noch nix machen, weil nu konzeptionell unklar ist, ob der Dialog die Eingabe entgegennimmt für
Löschung oder Befüllung
oder
optional Löschung und Befüllung
also wie ist der Plan: Soll der Dialog die Eingaben für optional Löschung und Befüllung entgegennehmen? (und die msgbox hinterher entfällt) -
Nein es gibt nur einen Dialog, da es nur einen Button "Insert" gibt. Beim klicken auf den Button öffnet sich die Messagebox.
Und die Messagebox scheint zu lügen, wenn sie sagt "clear before", denn wenn gecleart wird, dann wird ja nicht mehr befüllt.
Nein...
also wie ist der Plan: Soll der Dialog die Eingaben für optional Löschung und Befüllung entgegennehmen?
Könnte man machen, aber was hast du gegen meine MessagBox? -
ich denke, gute Benutzerführung ist, so wenig wie möglich herumklicksen zu müssen, und auch mit sowenig wie möglich aufpoppenden Dialogen konfrontiert zu werden.
TS71M schrieb:
Und dies muss ich jetzt in jedes Form einbauen, das auf den Dialog zugreift? Ist das nicht auch redundant?
Aber trotzdem würde ich dem dlgAutoInsert nicht die Daten in Sub New injekten oder sowas, sondern ich würde sie ihm geben genau zum Befüllen und nicht mehr (#4):
Aber das ist ja immer noch redundant, denn dasselbe muss ja in den anneren Aufrufer-Forms auch passieren. Kann man auslagern - aber wohin?
Also ich habs jetzt als Shared Sub ins dlgAutoInsert gepackt, und dann siehts im frmAufrufer so aus:TryAutoFill
ist die korrekte Bezeichnung der Methode, denn wir wissen nicht, ob überhaupt und wenn ja, wie autogefillt wird.
Und der Dialog (beachte den Unterschied von Shared und ObjektMethode!):VB.NET-Quellcode
- Public Class dlgAutoInsert
- Public Shared Sub TryAutoFill(owner As Form, bs As BindingSource)
- Using dlg = New dlgAutoInsert
- If dlg.ShowDialog(owner) <> Windows.Forms.DialogResult.OK Then Return
- Dim drv = DirectCast(bs.Current, DataRowView)
- dlg.FillDatarowView(drv)
- bs.ResetCurrentItem()
- End Using
- End Sub
- Public Sub FillDatarowView(drv As DataRowView)
- Dim ubound = drv.DataView.Table.Columns.Count - 1
- If Me.ActiveControl Is btClearFill Then
- For i = 3 To ubound
- drv(i) = 0D
- Next
- End If
- ubound = Math.Min(ubound, CInt((MonthCalendar1.SelectionRange.End - MonthCalendar1.SelectionRange.Start).TotalDays))
- For i = 3 To ubound
- drv(i) = NumericUpDown1.Value
- Next
- End Sub
- End Class
ps: Die Berechnungen sind für deine Anwendung sicher falsch - hauptsache, es tut sich was.Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()
-
Hey super, vielen Dank für die Arbeit, die du dir gemacht hast. Hat ein bisschen gedauert durchzusteigen, aber ich denke, ich hab's jetzt.
Leider funktioniert in deinem Beispiel die "fill" Methode gar nicht.
Aufrufendes Form
VB.NET-Quellcode
- Private Sub dgvSandGravel_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgvSandGravel.CellContentClick
- With dgvActual.CurrentRow
- If e.ColumnIndex <> .Cells(8).ColumnIndex Then Return 'Kann nicht direkt die eine Zelle wählen, da es mehrere DataGridViews sind; aber immer die Zelle 8
- If .Cells(1).Value IsNot DBNull.Value And .Cells(7).Value IsNot DBNull.Value Then 'sind MussFelder; sonst gibt's Alarm...
- Using dlg As New fmPlanAutoInsert
- If dlg.ShowDialog(Me) <> Windows.Forms.DialogResult.OK Then Return
- Dim drv = DirectCast(AppPlanBindingSource(e.RowIndex), DataRowView)
- dlg.ClearFillRow(drv)
- AppPlanBindingSource.ResetCurrentItem()
- End Using
- End If
- End With
- End Sub
Und im AutoInsert
VB.NET-Quellcode
- Public Shared Sub TryAutoFill(ByVal owner As Form, ByVal bs As BindingSource)
- Using frmPlanAutoInsert = New fmPlanAutoInsert
- If frmPlanAutoInsert.ShowDialog(owner) <> Windows.Forms.DialogResult.OK Then Return
- Dim drv = DirectCast(bs.Current, DataRowView)
- frmPlanAutoInsert.ClearFillRow(drv)
- bs.ResetCurrentItem()
- End Using
- End Sub
- Public Sub ClearFillRow(ByVal drv As DataRowView)
- If Me.ActiveControl Is btClearFill Then
- For i = 22 To 74
- drv(i) = 0D
- Next
- TryAutoFill(drv)
- End If
- If Me.ActiveControl Is btInsert Then TryAutoFill(drv)
- End Sub
- Public Sub TryAutoFill(ByVal drv As DataRowView)
- Dim StartWeek As Integer = GetKW(dtpStart.Value) + 21 'Ab Spalte 21
- Dim EndWeek As Integer = GetKW(dtpEnd.Value) + 21
- Dim StartDate As Date = dtpStart.Value
- Select Case rbEndsAfter.Checked
- Case True
- Select Case rbDays.Checked
- Case True 'days
- EndWeek = GetKW(dtpStart.Value.AddDays(nudApps.Value * nudPeriod.Value)) + 21
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value / 7)
- drv(i) = nudRate.Value
- Next
- Case False 'weeks
- EndWeek = GetKW(dtpStart.Value.AddDays(nudApps.Value * nudPeriod.Value * 7)) + 21
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value)
- drv(i) = nudRate.Value
- Next
- End Select
- Case False
- Select Case rbDays.Checked
- Case True 'days
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value / 7)
- drv(i) = nudRate.Value
- Next
- Case False 'weeks
- For i = StartWeek - 1 To EndWeek Step CInt(nudPeriod.Value)
- drv(i) = nudRate.Value
- Next
- End Select
- End Select
- End Sub
Funzt...
Allerdings noch eine Frage dazu:
Das läuft
Aber warum das nicht???
-
Ähnliche Themen
-
4 Benutzer haben hier geschrieben
- TS71M (10)
- ErfinderDesRades (10)
- RodFromGermany (6)
- Gast (4)