DataGridView als User die Spaltenbreiten in Einstellungen festlegen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    DataGridView als User die Spaltenbreiten in Einstellungen festlegen

    Hallo,

    ich würde in einem DataGridView gerne die Spaltenbreiten abspeichern. Im Moment setzte ich im Control die Spaltenbreiten fest, aber das kann sich ja auch mal wieder ändern.
    Wäre schön wenn man im laufenden Programm eine Spalte so groß macht wie man möchte und dann ist die beim nächsten Start auch wieder so.
    Jetzt dachte ich mache ich ein Array mit Width Werten und eine List mit den jeweiligen DatagridviewColumns und kann das dann entsprechend zuordnen und in den Einstellungen hinterlegen.

    Aber mein DGV hat ja eigentlich gar keine Spalten, sondern bildet ja die Spalten einer dahinterliegenden DataTable ab. Deswegen weiß ich nicht ob ich da eigentlich an der falschen Stelle rumwurstel.

    Viele Grüße

    Haudruferzappeltnoch schrieb:

    ein Array mit Width Werten und eine List mit den jeweiligen DatagridviewColumns und kann das dann entsprechend zuordnen und in den Einstellungen hinterlegen.
    Ja so in der art täte (und hab ich auch schon) ich das auch machen. Spaltenbreiten + Spaltennamen speichern.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Haudruferzappeltnoch schrieb:

    Aber mein DGV hat ja eigentlich gar keine Spalten, sondern bildet ja die Spalten einer dahinterliegenden DataTable ab.
    Macht doch nix. Trotzdem hat doch Dein DGV Spalten und Spaltenbreiten. Die kannst Du festlegen. Natürlich am besten, nachdem die Daten geladen wurden.
    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.
    @Haudruferzappeltnoch Mach Dir eine eigene Settings-Klasse, da geht auch eine List(Of Integer), diese Settings kannst Du speichern wo immer Du willst.
    Hier mal ne C#-Variante:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.IO.Compression;
    5. using System.Runtime.Serialization.Formatters.Binary;
    6. using System.Xml.Serialization;
    7. namespace SettingsBinAndXml
    8. {
    9. /// <summary>
    10. /// Klasse, die die Settings hält, speichert und lädt
    11. /// </summary>
    12. [Serializable]
    13. public class Settings
    14. {
    15. /// <summary>Settings-Member</summary>
    16. public int Port { get; set; }
    17. /// <summary>Settings-Member</summary>
    18. public string User { get; set; }
    19. /// <summary>Settings-Member</summary>
    20. public List<int> Values { get; set; }
    21. /// <summary>
    22. /// Pfad zur Settings-Datei,
    23. /// wird nicht mit abgespeichert
    24. /// </summary>
    25. [NonSerialized]
    26. [XmlIgnore]
    27. private string Path;
    28. /// <summary>
    29. /// parameterloser Konstruktor zur Serialisierung
    30. /// </summary>
    31. public Settings()
    32. {
    33. this.Values = new List<int>();
    34. }
    35. /// <summary>
    36. /// Konstruktor
    37. /// </summary>
    38. /// <param name="path">Pfad zur Datei</param>
    39. public Settings(string path)
    40. : this()
    41. {
    42. this.Path = path;
    43. }
    44. /// <summary>
    45. /// Überschrieben zur Test-Ausgabe
    46. /// </summary>
    47. /// <returns></returns>
    48. public override string ToString()
    49. {
    50. return string.Format("{0}, {1}, {2}", this.User, this.Port, this.Values.Count);
    51. }
    52. /// <summary>
    53. /// Speichern der Settings als XML-Datei
    54. /// </summary>
    55. internal void SaveXml()
    56. {
    57. // Serialize object to a XML file.
    58. using (StreamWriter sw = new StreamWriter(this.Path))
    59. {
    60. XmlSerializer x = new XmlSerializer(this.GetType());
    61. x.Serialize(sw, this);
    62. }
    63. }
    64. /// <summary>
    65. /// Laden der Settings
    66. /// </summary>
    67. /// <param name="path">Pfad der XML-Datei</param>
    68. /// <returns>die geladenen DataAll</returns>
    69. internal static Settings LoadXml(string path)
    70. {
    71. Settings settings = new Settings();
    72. try
    73. {
    74. // Deserialize text file to a new object.
    75. using (StreamReader sr = new StreamReader(path))
    76. {
    77. XmlSerializer x = new XmlSerializer(settings.GetType());
    78. settings = (Settings)x.Deserialize(sr);
    79. }
    80. }
    81. catch
    82. {
    83. // nix tun, die Settings-Instanz ist nicht valid,
    84. // es werden die Default-Werte zurückgegeben
    85. }
    86. settings.Path = path;
    87. return settings;
    88. }
    89. /// <summary>
    90. /// Speichern der Settings
    91. /// </summary>
    92. internal void WriteToBin()
    93. {
    94. // Serialize object to a bin file.
    95. using (FileStream fs = new FileStream(this.Path, FileMode.Create))
    96. {
    97. BinaryFormatter binFormatter = new BinaryFormatter();
    98. using (GZipStream fs2 = new GZipStream(fs, CompressionMode.Compress))
    99. {
    100. binFormatter.Serialize(fs2, this);
    101. }
    102. }
    103. }
    104. /// <summary>
    105. /// Einlesen der Settings
    106. /// </summary>
    107. /// <param name="path">der Dateiname</param>
    108. /// <returns>die gelesene oder die neue Settingsinstanz</returns>
    109. internal static Settings ReadFromBin(string path)
    110. {
    111. // Serialize settings to a bin file.
    112. Settings settings = new Settings();
    113. try
    114. {
    115. using (FileStream fs = new FileStream(path, FileMode.Open))
    116. {
    117. BinaryFormatter binFormatter = new BinaryFormatter();
    118. using (GZipStream fs2 = new GZipStream(fs, CompressionMode.Decompress))
    119. {
    120. settings = (Settings)binFormatter.Deserialize(fs2);
    121. }
    122. }
    123. }
    124. catch
    125. {
    126. }
    127. settings.Path = path;
    128. return settings;
    129. }
    130. }
    131. }

    C#-Quellcode

    1. private void btnTemp_Click(object sender, EventArgs e)
    2. {
    3. string path = "D:\\Temp\\Settings.xml";
    4. Settings data = Settings.LoadXml(path);
    5. data.User = "Ich";
    6. data.Port = 44;
    7. data.Values.Add(19);
    8. data.SaveXml();
    9. MessageBox.Show(data.ToString());
    10. }
    11. private void btnBinaryOut_Click(object sender, EventArgs e)
    12. {
    13. Settings data = new Settings("D:\\Temp\\Settings.bin");
    14. data.User = "Ich";
    15. data.Port = 45;
    16. data.Values.Add(20);
    17. data.WriteToBin();
    18. MessageBox.Show(data.ToString());
    19. }



    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!
    @Haudruferzappeltnoch Diese Settings haben nix zu tun mit den Settings, die Dir in den Projekteigenschaften angeboten werden.
    Dies ist eine eigene Klasse, in die Du reinschreiben kannst, was immer Du benötigst.
    Im Beispiel tragen sie den Kommentar Settings-Member.
    Erweitere lediglich die Properties oben im Code.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.IO.Compression
    3. Imports System.Runtime.Serialization.Formatters.Binary
    4. Imports System.Xml.Serialization
    5. ''' <summary>
    6. ''' Klasse, die die Settings hält, speichert und lädt
    7. ''' </summary>
    8. <Serializable>
    9. Public Class Settings
    10. ''' <summary>Settings-Member</summary>
    11. Public Property Port As Integer
    12. ''' <summary>Settings-Member</summary>
    13. Public Property User As String
    14. ''' <summary>Settings-Member</summary>
    15. Public Property Values As List(Of Integer)
    16. ''' <summary>
    17. ''' Pfad zur Settings-Datei,
    18. ''' wird nicht mit abgespeichert
    19. ''' </summary>
    20. <NonSerialized>
    21. <XmlIgnore>
    22. Private Path As String
    23. ''' <summary>
    24. ''' parameterloser Konstruktor zur Serialisierung
    25. ''' </summary>
    26. Public Sub New()
    27. Values = New List(Of Integer)()
    28. End Sub
    29. ''' <summary>
    30. ''' Konstruktor
    31. ''' </summary>
    32. ''' <param name="path">Pfad zur Datei</param>
    33. Public Sub New(ByVal path As String)
    34. Me.New()
    35. Me.Path = path
    36. End Sub
    37. ''' <summary>
    38. ''' Überschrieben zur Test-Ausgabe
    39. ''' </summary>
    40. ''' <returns></returns>
    41. Public Overrides Function ToString() As String
    42. Return String.Format("{0}, {1}, {2}", User, Port, Values.Count)
    43. End Function
    44. ''' <summary>
    45. ''' Speichern der Settings als XML-Datei
    46. ''' </summary>
    47. Friend Sub SaveXml()
    48. ' Serialize object to a XML file.
    49. Using sw As StreamWriter = New StreamWriter(Path)
    50. Dim x As XmlSerializer = New XmlSerializer([GetType]())
    51. x.Serialize(sw, Me)
    52. End Using
    53. End Sub
    54. ''' <summary>
    55. ''' Laden der Settings
    56. ''' </summary>
    57. ''' <param name="path">Pfad der XML-Datei</param>
    58. ''' <returns>die geladenen DataAll</returns>
    59. Friend Shared Function LoadXml(ByVal path As String) As Settings
    60. Dim settings = New Settings()
    61. Try
    62. ' Deserialize text file to a new object.
    63. Using sr As StreamReader = New StreamReader(path)
    64. Dim x As XmlSerializer = New XmlSerializer(settings.GetType())
    65. settings = CType(x.Deserialize(sr), Settings)
    66. End Using
    67. Catch
    68. ' nix tun, die Settings-Instanz ist nicht valid,
    69. ' es werden die Default-Werte zurückgegeben
    70. End Try
    71. settings.Path = path
    72. Return settings
    73. End Function
    74. ''' <summary>
    75. ''' Speichern der Settings
    76. ''' </summary>
    77. Friend Sub WriteToBin()
    78. ' Serialize object to a bin file.
    79. Using fs As FileStream = New FileStream(Path, FileMode.Create)
    80. Dim binFormatter As BinaryFormatter = New BinaryFormatter()
    81. Using fs2 As GZipStream = New GZipStream(fs, CompressionMode.Compress)
    82. binFormatter.Serialize(fs2, Me)
    83. End Using
    84. End Using
    85. End Sub
    86. ''' <summary>
    87. ''' Einlesen der Settings
    88. ''' </summary>
    89. ''' <param name="path">der Dateiname</param>
    90. ''' <returns>die gelesene oder die neue Settingsinstanz</returns>
    91. Friend Shared Function ReadFromBin(ByVal path As String) As Settings
    92. ' Serialize settings to a bin file.
    93. Dim settings As Settings = New Settings()
    94. Try
    95. Using fs As FileStream = New FileStream(path, FileMode.Open)
    96. Dim binFormatter As BinaryFormatter = New BinaryFormatter()
    97. Using fs2 As GZipStream = New GZipStream(fs, CompressionMode.Decompress)
    98. settings = CType(binFormatter.Deserialize(fs2), Settings)
    99. End Using
    100. End Using
    101. Catch
    102. End Try
    103. settings.Path = path
    104. Return settings
    105. End Function
    106. End Class

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim path As String = "D:\Temp\Settings.xml"
    3. Dim data As Settings = Settings.LoadXml(path)
    4. data.User = "Ich"
    5. data.Port = 44
    6. data.Values.Add(19)
    7. data.SaveXml()
    8. MessageBox.Show(data.ToString())
    9. End Sub
    10. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    11. Dim data As Settings = New Settings("D:\Temp\Settings.bin")
    12. data.User = "Ich"
    13. data.Port = 45
    14. data.Values.Add(20)
    15. data.WriteToBin()
    16. MessageBox.Show(data.ToString())
    17. End Sub


    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!
    Wenn Du nur die Spaltenbreiten in den "normalen" Settings speichern willst, kannst Du sie notfalls auch zu einem String mergen und später wieder auseinanderpfriemeln.
    Also

    VB.NET-Quellcode

    1. 'speichern
    2. Dim ColumnWidths = DeinDGV.Columns.Cast(Of DataGridViewColumn).Select(Function(x) x.Width)
    3. Dim StringForSettings = String.Join(";"c, ColumnWidths)
    4. My.Settings.DerNameDerEinstellung = StringForSettings
    5. '[…]
    6. 'laden
    7. Dim SavedData = My.Settings.DerNameDerEinstellung
    8. Dim ColumnWidths = SavedData.Split(";"c).Select(Function(x) Integer.Parse(x))
    9. For i = 0 To ColumnWidths.Count - 1
    10. DeinDGV.Columns(i).Width = ColumnWidths(i)
    11. Next
    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.
    @Haudruferzappeltnoch Mit meinem Code kannst Du auch ein Array speichern.
    Du musst es nur deklarieren und instanziieren (ihm Werte zuweisen).
    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!

    Haudruferzappeltnoch schrieb:

    es wäre sicherlich sehr nützlich das zu tun.
    Dann füge die Settings-Datei einem neuen Projekt hinzu und spiele ein wernig damit herum, um ein Gefühl für zu bekommen.
    In meinen Programmen nutze ich ausschließlich "eigene" Settings.
    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!
    Läuft die Anwendung nur auf einem PC?
    Meine läuft z.B. in einem Netzwerk mit mehreren Usern und ich selbst melde mich auch mal an einem anderen PC an. Ich persistiere die DGV-Spaltenbreiten mit in der Datenbank
    und mach das so, wie @VaporiZed das schon vorgeschlagen hat. Da der User bei mir die anzuzeigenden Spalten auswählen kann, ist das ganze komplexer - ist die Frage ob du sowas auch mal vor hast.
    Ich speicher das mit Namen der Column, der Width und ob die Visible ist oder nicht. Sieht dann in etwa so aus:



    Ich kann damit also auf jedem PC meine persönlichen "Einstellungen" abspeichern und abrufen.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Ich hoffe es passt noch ins Thema rein:

    An sich nutze ich das DGV nur zur Anzeige. Man kann jedoch obwohl ich nichts in der Richtung programmiere,
    die Spalte des DGVs sortieren wenn man den Spaltenkopf anklickt. Da ich das wie gesagt nicht selbst eingebaut habe, weiß ich garnicht wo diese Sortierung stattfindet und auch nicht wie ich sie beeinflussen kann.
    Denn momentan sortiert er auch numerische Werte alphabetisch. Vielleicht ist das ja der Standard?
    Sry es war die DataTable, die hatte ich noch nicht auf den richtigen Typ umgestellt.

    Das kann man im DGV einstellen: Wähle es im Designer, dann oben rechts auf den kleinen SmartTag [>] klicken, dann Spalten bearbeiten… und dann kannst Du bei jeder Spalte im PropertyFenster fast ganz unten das Sortierverhalten einstellen (SortMode). Ich bin da meist ziemlich rigoros und deaktiviere das. Meine User müssen nehmen, was ich vorgebe :evil:
    Bilder
    • DgvSortMode.png

      30,56 kB, 991×284, 41 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.

    VaporiZed schrieb:

    (SortMode). Ich bin da meist ziemlich rigoros und deaktiviere das. Meine User müssen nehmen, was ich vorgebe
    Findich ich nicht empfehlenswert.
    Fast immer ist das Sortieren von Daten dem User eine nützliche Hilfe.

    Ansonsten kann man die Sortierung auch an der BindingSource.Sort-Property einstellen.