C# Objekt Namen herausfinden + ein wenig mehr

    • C#

    Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

      C# Objekt Namen herausfinden + ein wenig mehr

      Hallo Leute,

      hier eine kleine Klasse, mit der Ihr den Namen eines Objektes erhaltet, um dieses ansprechen zukönnen.
      Außerdem noch ein bisschen was für DataGridViewColumns, um eine Spalte oder deren Index zu erhalten anhand des HeaderTextes.

      Spoiler anzeigen

      C#-Quellcode

      1. using System.Collections.Generic;
      2. using System.Linq;
      3. using System.Data;
      4. using System.Windows.Forms;
      5. static class Communicator
      6. {
      7. /// <summary>
      8. /// Uses Reflection to receive the Designer Name of the passed Object on that Form
      9. /// <para>Works for WPF Windows aswell</para>
      10. /// </summary>
      11. /// <param name="target">object you want the name of</param>
      12. /// <param name="parent">Form Control on which that object is hosted</param>
      13. /// <returns>returns the Designer Name</returns>
      14. public static string getObjectName(object target, Form parent)
      15. {
      16. List<System.Reflection.FieldInfo> parentInfos = new List<System.Reflection.FieldInfo>(
      17. parent.GetType().GetFields(
      18. System.Reflection.BindingFlags.Public |
      19. System.Reflection.BindingFlags.NonPublic |
      20. System.Reflection.BindingFlags.Instance
      21. ));
      22. return parentInfos.Find(
      23. info=>target==info.GetValue(parent)
      24. ).Name;
      25. }
      26. /// <summary>
      27. /// Gets a DataGridViewColumn by searching for the passed HeaderText
      28. /// </summary>
      29. /// <param name="headerText">The HeaderText displayed by the searched column</param>
      30. /// <param name="targetView">The DataGridView that contains that column</param>
      31. /// <returns>returns DataGridViewColumn with matching HeaderText</returns>
      32. public static DataGridViewColumn getColumnByHeader(string headerText, DataGridView targetView)
      33. {
      34. return targetView.Columns.Cast<DataGridViewColumn>()
      35. .Where(c=>c.HeaderText==headerText)
      36. .Select(c=>c).ToList().FirstOrDefault();
      37. }
      38. /// <summary>
      39. /// Gets the index of a DataGridViewColumn by searching for the passed HeaderText
      40. /// </summary>
      41. /// <param name="headerText">The HeaderText displayed by the searched column</param>
      42. /// <param name="targetView">The DataGridView that contains that column</param>
      43. /// <returns>returns index of DataGridViewColumn with matchin HeaderText</returns>
      44. public static int getColumnIndexByHeader(string headerText, DataGridView targetView)
      45. {
      46. return targetView.Columns.Cast<DataGridViewColumn>()
      47. .Where(c=>c.HeaderText==headerText)
      48. .Select(c=>c.Index).ToList().FirstOrDefault();
      49. }
      50. }



      Ein Aufruf sieht wie folgt aus:
      - dgv_ComputerDB == DataGridView
      - "Benutzer" == HeaderText einer DataGridViewColumn


      Spoiler anzeigen

      C#-Quellcode

      1. void test()
      2. {
      3. var objectName = Communicator.getObjectName(dgv_ComputerDB.Columns[0], this);
      4. var columnByHeader = Communicator.getColumnByHeader("Benutzer", dgv_ComputerDB);
      5. var columnIndex = Communicator.getColumnIndexByHeader("Benutzer", dgv_ComputerDB);
      6. var combination = Communicator.getObjectName(
      7. Communicator.getColumnByHeader("Benutzer", dgv_ComputerDB)
      8. , this
      9. );
      10. }

      C#-Quellcode

      1. public static DataGridViewColumn getColumnByHeader(DataGridView targetView,string headerText)
      2. {
      3. return targetView.Columns.Cast<DataGridViewColumn>()
      4. .FirstOrDefault(c=>c.HeaderText==headerText)
      5. }
      6. public static int getColumnIndexByHeader(DataGridView targetView,string headerText)
      7. {
      8. var a = targetView.Columns.Cast<DataGridViewColumn>()
      9. .FirstOrDefault(c=>c.HeaderText==headerText);
      10. return a == null ? -1 : a.Index;
      11. }

      nicht ganz so viel unnötiges LinQ.
      Was du gemacht hast war enumerieren und dabei casten(Cast), davon ein paar bestimmte auswählen(Where), die auf das schema passen, davon selektieren(Select) und genau dasselbe beibehalten(also eigt. nichts tun), dann in eine Liste konvertieren(ToList), was dafür sorgt, dass komplett alles durch iteriert werden muss, um am Ende das erste Element auszuwählen oder default(T) zurückzugeben.
      Dabei kann man direkt FirstOrDefault verwenden, denn sobald das erste korrekte gefunden wird, muss nicht mehr weiter gesucht werden. Also das schlimmste dabei war das ToList.

      Deine getColumnIndexByHeader gibt außerdem 0 zurück wenn nichts gefunden wird, sollte aber eher -1 oder sonst ein ungültiger wert sein...evtl. auch exception werfen...

      wenn man außerdem bereits getColumnByHeader verwendet, dann sollte man nicht anschließend den Index holen schließlich kann man ja einfach columnByHeader.Index verwenden und hat nicht noch ein erneutes durchsuchen.

      Das getObjectName sollte allgemein nie verwendet werden, ich meine warum ist der Name des feldes interessant? Es sei denn es ist für debugzwecke?
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---
      Hallo

      Ein kleiner Nachtrag.
      Den Namen eines Objects kann man seit C# 6 und VS 2015 wie folgt einfacher und imho performanter bekommen:
      WriteLine(nameof(person.Address.ZipCode)
      Siehe : docs.microsoft.com/en-us/dotne…reference/keywords/nameof

      Grüße Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##