Announcement

Collapse
No announcement yet.

DataGrid

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DataGrid

    Hi,

    ich hätte 3 Fragen zum DataGrid wo ich so auf die Schnelle nichts gefunden habe.

    1. Wie kann ich das Grid auf Read-Only setzen, damit man einzelne Felder nicht mehr ändern kann.

    2. Wie kann man einstellen, das wenn man in eine Zeile klickt die "gesamte" Zeile markiert ist und nicht nur ein Feld oder sonstwas...

    3. Nehmen wir an ich hab ein Grid wo 3 Spalten angezeigt werden: ID, Name, Vorname
    Wenn ich jetzt eine Zeile markiere z. B. und nen Button anklicke oder ne Zeile doppelt anklicke will ich z. B. in nem neuen Form weitere Infos zu diesem Datensatz anzeigen. Wie kann ich diesen Datensatz in dem Grid ansprechen?

    Danke für Eure Hilfe!!!

  • #2
    Hallo,

    zu Frage 1: Dazu wird die DataGrid-Eigenschaft <b>ReadOnly</b> im Properties-Editor auf True gesetzt.

    zu Frage 2: Die <b>Select</b>-Methode markiert die vollständige Zeile. Um die Zeile zu ermittelt, liefert die DataGrid-Methode <b>HitTest</b> die notwendigen Rohdaten zurück. Über die Eigenschaft <b>CurrentCell</b> wird die angeklickte Zelle als aktuelle Zelle markiert, so dass dann auch die Zeile selbst feststeht:

    <pre>
    <b>private</b> <b>void</b> dataGrid1_MouseUp(<b>object</b> sender, System.Windows.Forms.MouseEventArgs e)
    {
    Point pt = <b>new</b> Point(e.X, e.Y);
    DataGrid.HitTestInfo aHTI = dataGrid1.HitTest(pt);
    dataGrid1.CurrentCell = <b>new</b> DataGridCell(aHTI.Row, aHTI.Column);
    dataGrid1.Select(aHTI.Row);
    }
    </pre>

    zu Frage 3: Für diese Aufgabe gibt es mehrere Alternativen. Die Antwort auf die Frage "Welche Alternative ist die Beste?" hängt davon ab, wie schnell und wie häufig die Anwendung auf die originalen Daten aus der Datenbank zugreifen kann (oder darf).

    Version 1: Primärschlüssel des im DataGrid markierten Datensatzes auslesen, um diesen im zweiten Formular einzeln über eine separate SqlCommand-Abfrage nachzuladen:

    <pre>
    <b>private</b> <b>void</b> button2_Click(<b>object</b> sender, System.EventArgs e)
    {
    CurrencyManager aCM;
    aCM = (CurrencyManager)BindingContext[dataSet11, <font color="#9933CC">&quot;Customers&quot;</font>];
    <b>string</b> sTxt = dataSet11.Customers.Rows[aCM.Position][0].ToString();
    MessageBox.Show(sTxt);
    }
    </pre>

    Version 2: Das zweite Formular an die gleiche Datenquelle binden, so dass auch das zweite Formular mit der gleichen Datenmenge arbeitet. Die zweite Version unterstützt die Kombination von ReadOnly-DataGrid und separatem Bearbeitungsformular für die Datensätze. Die Änderungen an der Datenmenge werden erst dann wirksam, wenn die Methode <b>EndCurrentEdit</b> aufgerufen wird:

    Aufruf im Hauptformular:
    <pre>
    <b>private</b> <b>void</b> button3_Click(<b>object</b> sender, System.EventArgs e)
    {
    Form2 aFrm2 = <b>new</b> Form2();
    CurrencyManager aCM;
    aCM = (CurrencyManager)BindingContext[dataSet11, <font color="#9933CC">&quot;Customers&quot;</font>];
    aFrm2.DoEditData(aCM);
    }
    </pre>
    Implementierung im 2. Formular:

    <li> Die Eigenschaft <b>Current</b> des CurrencyManagers stellt das DataRowView-Objekt zur Verfügung, so dass die Typumwandlung notwendig ist. </li>

    <li> Über die Eigenschaft <b>Position</b> gleichen beide Formulare den angezeigten Datensatz ab. Damit an dieser Stelle die Datensätze mit Löschmarkierung nicht stören, greift das Programm auf DataView anstelle von DataTable zurück. Im Gegensatz zur DataTable blendet ein DataView die als gelöscht markierten DataRow-Objekte eines DataSets aus (siehe RowStateFilter). Der CurrencyManager arbeitet intern nach dem gleichen Prinzip.</li>

    <li> Die Controls der 2. Formulars werden nicht über den Eigenschaftsdialog visuell, sondern im Sourcecode von Hand an die Datenquelle gebunden </li>

    <pre>
    <b>public</b> <b>void</b> DoEditData(CurrencyManager aCM)
    {
    DataRowView aDRV = aCM.Current <b>as</b> DataRowView;
    DataView aDV = aDRV.DataView;
    <b>this</b>.BindingContext[aDV].Position = aCM.Position;
    textBox1.DataBindings.Add(<font color="#9933CC">&quot;Text&quot;</font>, aDV, <font color="#9933CC">&quot;CustomerID&quot;</font>);
    textBox2.DataBindings.Add(<font color="#9933CC">&quot;Text&quot;</font>, aDV, <font color="#9933CC">&quot;CompanyName&quot;</font>);
    <b>if</b> (<b>this</b>.ShowDialog() == DialogResult.OK)
    aCM.EndCurrentEdit();
    <b>else</b>
    aCM.CancelCurrentEdit();
    }

    </pre&gt

    Comment


    • #3
      Hallo,

      gibt es nicht auch eine wie auch immer geartete Möglichkeit dem DataGrid mitzuteilen daß immer nur eine ganze Zeile markiert sein soll? So möchte ich zum Beispiel verhindern daß wenn das Grid den Focus hat mit der Tastatur doch wieder einzelne Zellen markiert werden können. Sollte halt so aussehen wie im Delphi-DBGrid bei aktivierter Option "RowSelect" oder so ähnlich.

      Stefa

      Comment

      Working...
      X