Fensterposition speichern

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von jan99.

    Fensterposition speichern

    Moin!

    ich möchte ein Fenster in seiner Position speichern und beim nächsten öffnen wieder dort öffnen.

    My.settings habe ich hierzu gefunden und folgendes implementiert:

    VB.NET-Quellcode

    1. Private Sub frm_GrundstDoku_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. ' Me.TopMost = True
    3. Me.Location = My.Settings.FormLocation
    4. ....


    VB.NET-Quellcode

    1. Private Sub Form1_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
    2. My.Settings.FormLocation = Me.Location
    3. End Sub
    4. Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    5. My.Settings.Save()
    6. End Sub


    FormLocation war zunächst unbekannt und über das Kontextmenü wurde mir eine Fehlerbehebung angeboten die dann eine Settings.Designer.vb angelegt hat.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. '------------------------------------------------------------------------------
    2. ' <auto-generated>
    3. ' Dieser Code wurde von einem Tool generiert.
    4. ' Laufzeitversion:4.0.30319.42000
    5. '
    6. ' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
    7. ' der Code erneut generiert wird.
    8. ' </auto-generated>
    9. '------------------------------------------------------------------------------
    10. Option Strict On
    11. Option Explicit On
    12. Namespace My
    13. <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
    14. Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0"), _
    15. Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
    16. Partial Friend NotInheritable Class MySettings
    17. Inherits Global.System.Configuration.ApplicationSettingsBase
    18. Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
    19. #Region "Funktion zum automatischen Speichern von My.Settings"
    20. #If _MyType = "WindowsForms" Then
    21. Private Shared addedHandler As Boolean
    22. Private Shared addedHandlerLockObject As New Object
    23. <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
    24. Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
    25. If My.Application.SaveMySettingsOnExit Then
    26. My.Settings.Save()
    27. End If
    28. End Sub
    29. #End If
    30. #End Region
    31. Public Shared ReadOnly Property [Default]() As MySettings
    32. Get
    33. #If _MyType = "WindowsForms" Then
    34. If Not addedHandler Then
    35. SyncLock addedHandlerLockObject
    36. If Not addedHandler Then
    37. AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
    38. addedHandler = True
    39. End If
    40. End SyncLock
    41. End If
    42. #End If
    43. Return defaultInstance
    44. End Get
    45. End Property
    46. Public Property FormLocation As Point
    47. End Class
    48. End Namespace
    49. Namespace My
    50. <Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
    51. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    52. Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
    53. Friend Module MySettingsProperty
    54. <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
    55. Friend ReadOnly Property Settings() As Global.EBL_GStkHistorie.My.MySettings
    56. Get
    57. Return Global.EBL_GStkHistorie.My.MySettings.Default
    58. End Get
    59. End Property
    60. End Module
    61. End Namespace



    Im Web hatte ich den Hinweis gefunden, dass die Settings unter C:\Users\Benutzername\AppData\Local\Microsoft gespeichert werden.

    Aber dort wird nix angelegt und auch das Fenster wird weiterhin an der alten Position geöffnet.

    In der Form-Eigenschaft steht für StartPosition der Wert WindowsDefaultBounds.

    Kann mir jemand weiterhelfen`?

    Gruß Jan
    Lege in den Projekt-Einstellungen beim Reiter Einstellungen 2 Integer-Werte an: X und Y. Darin speicherst Du dann die Formposition. My.Settings.Save() brauchst Du standardmäßig nicht. Beim Start nimmst Du die Werte her und setzt die Formposition darauf, beim Schließen vice versa. Fertig.

    VB.NET-Quellcode

    1. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. Me.Left = My.Settings.FormPositionX
    3. Me.Top = My.Settings.FormPositionY
    4. End Sub
    5. Private Sub FrmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    6. My.Settings.FormPositionX = Me.Left
    7. My.Settings.FormPositionY = Me.Top
    8. End Sub


    ##########

    Da geht bestimmt auch was mit DataBinding, aber für den Anfang sollte es reichen.
    Bilder
    • CreateSettings.png

      18,22 kB, 588×245, 37 mal angesehen
    • AutoSave.png

      22,46 kB, 494×468, 32 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    @jan99 Ich hab da ne Klasse, die Du als Basisklasse jeder Form gibst, deren Position gespeichert und restauriert werden soll.
    Feddich.
    ====
    Die Datei wird hier abgelegt: Users\User\AppData\Local\

    Das kannst Du aber beliebig anpassen.
    Ich denke, dass Du den Code problemlos von C# nach VBN.NET übersetzen kannst.
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Data;
    3. using System.Drawing;
    4. using System.Windows.Forms;
    5. namespace MyTestProgram
    6. {
    7. public class FormBase : Form
    8. {
    9. #region Constants
    10. /// <summary>
    11. /// Pfad der XML-Datei der DataTable in Users\User\AppData\Local\
    12. /// </summary>
    13. private const string DataFolder = "MyFirma";
    14. /// <summary>
    15. /// Name der XML-Datei der DataTable in Users\User\AppData\Local\
    16. /// </summary>
    17. private const string DataFile = "MyFile.xml";
    18. #endregion Constants
    19. #region Static Member
    20. /// <summary>
    21. /// Pfad zur DataTable
    22. /// </summary>
    23. private static string _DataPath;
    24. /// <summary>
    25. /// DataTable mit den Form-Informationen
    26. /// </summary>
    27. private static DataTable _DataTable;
    28. #endregion Static Member
    29. #region Konstruktoren
    30. /// <summary>
    31. /// Statischer Konstruktor der Klasse FormBase
    32. /// </summary>
    33. static FormBase()
    34. {
    35. FormBase._DataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\" + FormBase.DataFolder + "\\" + FormBase.DataFile;
    36. FormBase.CreateTable();
    37. FormBase.LoadTable();
    38. }
    39. /// <summary>
    40. /// Standardkonstruktor der Klasse FormBase
    41. /// </summary>
    42. public FormBase()
    43. : base()
    44. {
    45. this.InitBaseClass();
    46. }
    47. /// <summary>
    48. /// Initialisierung der BaseClass-Funktionalität
    49. /// </summary>
    50. private void InitBaseClass()
    51. {
    52. this.StartPosition = FormStartPosition.Manual;
    53. }
    54. #endregion Konstruktoren
    55. #region Private DataTable Stuff
    56. /// <summary>
    57. /// Laden der DataTable`aus einer Datei
    58. /// </summary>
    59. private static void LoadTable()
    60. {
    61. FormBase._DataTable.Clear();
    62. try
    63. {
    64. System.IO.FileInfo fi = new System.IO.FileInfo(FormBase._DataPath);
    65. if (fi.Exists)
    66. {
    67. FormBase._DataTable.ReadXml(FormBase._DataPath);
    68. }
    69. }
    70. catch (Exception ex)
    71. {
    72. MessageBox.Show("File not found: " + FormBase._DataPath + "\n\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    73. }
    74. }
    75. /// <summary>
    76. /// Generieren der Einträge der DataTable
    77. /// </summary>
    78. private static void CreateTable()
    79. {
    80. // Für diese Datentypen ist kein XMLSchema-Eintrag erforderlich
    81. DataColumn title = new DataColumn("Title", typeof(string));
    82. DataColumn rect = new DataColumn("Bounds", typeof(Rectangle));
    83. FormBase._DataTable = new DataTable("FormSettings");
    84. FormBase._DataTable.Columns.Add(title);
    85. FormBase._DataTable.Columns.Add(rect);
    86. FormBase._DataTable.Constraints.Add("Key1", title, true); // "Key1" ist der Name der Einschränkung; IDColumn ist Primärschlüssel
    87. }
    88. /// <summary>
    89. /// Auslesen der Fensterposition,
    90. /// wenn sie in der Tabelle vorgefunden wurde
    91. /// </summary>
    92. /// <param name="name">Name des Fensters</param>
    93. /// <returns>die Fensterposition</returns>
    94. private static Rectangle GetBounds(string name)
    95. {
    96. DataRow rows = FormBase._DataTable.Rows.Find(name);
    97. if ((rows == null) ||
    98. (rows.ItemArray.Length < 2))
    99. {
    100. // nicht gefunden
    101. return Rectangle.Empty;
    102. }
    103. if (rows[1] is DBNull)
    104. {
    105. // nicht gefunden
    106. return Rectangle.Empty;
    107. }
    108. try
    109. {
    110. return (Rectangle)rows[1];
    111. }
    112. catch
    113. {
    114. // falscher Typ
    115. return Rectangle.Empty;
    116. }
    117. }
    118. /// <summary>
    119. /// Auslesen des Tabelleneintrags für ein eingetragenes Fenster
    120. /// </summary>
    121. /// <param name="name">Name des Fensters</param>
    122. /// <returns>Größe und Position</returns>
    123. private static Rectangle GetWindowRect(string name)
    124. {
    125. return FormBase.GetBounds(name);
    126. }
    127. /// <summary>
    128. /// Schreiben der Tabelleninformation
    129. /// </summary>
    130. /// <param name="name">Name des Fensters</param>
    131. /// <param name="rect">seine Größe und Position</param>
    132. private static void SetBounds(string name, Rectangle rect)
    133. {
    134. DataRow rows = FormBase._DataTable.Rows.Find(name);
    135. if (rows == null)
    136. {
    137. // nicht gefunden
    138. FormBase._DataTable.Rows.Add(new object[] { name, rect });
    139. return;
    140. }
    141. rows[0] = name;
    142. rows[1] = rect;
    143. }
    144. #endregion Private DataTable Stuff
    145. #region EventHandler
    146. /// <summary>
    147. /// Restaurieren der Fensterposition im Zustand
    148. /// .WindowState = FormWindowState.Normal;
    149. /// </summary>
    150. protected override void OnLoad(EventArgs e)
    151. {
    152. base.OnLoad(e);
    153. Rectangle rect = FormBase.GetWindowRect(this.Name);
    154. if (rect == Rectangle.Empty)
    155. {
    156. // Eintrag war nicht vorhanden oder Fenster war minimiert,
    157. // nun mit Default-Position und -Größe anzeigen
    158. this.StartPosition = FormStartPosition.WindowsDefaultLocation;
    159. return;
    160. }
    161. this.Location = rect.Location;
    162. if ((this.FormBorderStyle == FormBorderStyle.Sizable) ||
    163. (this.FormBorderStyle == FormBorderStyle.SizableToolWindow))
    164. {
    165. this.Size = rect.Size;
    166. }
    167. }
    168. /// <summary>
    169. /// Speichern der Größe und der Position
    170. /// des Dialogs beim Schließen,
    171. /// Abspeichern der Tabelle.
    172. /// </summary>
    173. protected override void OnFormClosing(FormClosingEventArgs e)
    174. {
    175. base.OnFormClosing(e);
    176. if (this.WindowState == FormWindowState.Normal)
    177. {
    178. FormBase.SetBounds(this.Name, this.Bounds);
    179. }
    180. else
    181. {
    182. // Minimized: .Location = { -32000, -32000 }, .Size = { 160, 27 }
    183. // Maximized: .Location = { -8, -8 }, .Size = { max. Fenstergröße }
    184. FormBase.SetBounds(this.Name, this.RestoreBounds);
    185. }
    186. FormBase._DataTable.WriteXml(FormBase._DataPath);
    187. }
    188. #endregion EventHandler
    189. }
    190. }
    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!
    Moin!

    erst dachte ich der Lösung sehr nahe zu sein. Bis ich dann die Einstellung setzen wollte my.settings beim Herunterfahren zu speichern.

    Da kam dann diese Meldung:


    Das "Problem" ist, dass meine Anwendung eine Konsolenanwendung ist, die dann eine Form öffnet.

    In der Konsole prüfe ich ab, ob die Parameter richtig übergeben wurden und wenn nicht wird ausgestiegen.

    Nun müsste ich alles in den Load verschieben und dann den Dialog automatisch wieder schließen, wenn Fehler vorliegen.
    :thumbdown:

    Oder gibt es noch einen anderen Weg???

    Jan
    Ah, die verschiwiegenen Details ;)
    Dann eben doch mit My.Settings.Save und My.Settings.Load
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ehm, nööö? Zumindest nicht mit dem Post#2-Code in ner normalen WinForms-App. OK, in der SubMain-WinForms-Kombi habe ich es nicht getestet.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    jan99 schrieb:

    wo soll das dann eingebaut werden?
    Mit meinem Code genügt Inherits FormBase. Feddich.
    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!
    My.Settings.Reload :rolleyes:
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Moin!

    in meinen Spoiler oben hatte ich den Code aus dem Designer hinterlegt.

    Wenn ich jetzt kompiliere, dann kommt es zu folgender Meldung:



    Die Meldung kommt auch, wenn ich die ..Designer.vb speichern will.

    Kann / Muss ich die Datei ändern oder löschen?

    Aber im Projektmappen-Explorer finde ich die Datei nicht!

    ????

    Gruß Jan