Frage

Ich habe eine ungebundene DataGridView (in VS 2008), von der eine Spalte einen Dateipfad enthält. Ich möchte die Zeichenfolge mit der Textrenderer -Klasse auf dem Columnwidthchanged -Ereignis formatieren, ohne den zugrunde liegenden Wert tatsächlich zu ändern. Das Problem ist, dass der Inhalt der Tabelle gespeichert wird, wenn das Formular geschlossen ist und ich den formatierten Wert nicht speichern möchte. Ich denke, ich bin einfach zu tief, um die offensichtliche Lösung zu sehen, also bin ich auf euch angewiesen, um darauf hinzuweisen :-).

Die Idee ist, dies anzuzeigen:

C: Programme Microsoft Visual Studio 8 SDK V2.0 bin gacutil.exe

... wie dies (abhängig von der Breite der Spalte):

C: Programme microso… gacutil.exe


Es scheint, dass ich zu früh gesprochen habe. Ich bekomme einige sehr seltsame Ergebnisse von textrenderer.measuretext (). Wenn ich den Pfadwert als "C: Dokumente und Einstellungen jluce meine Dokumente Downloads" festhötze, endet er als C: Dokumente und Einstellungen jluce m ... downloads 0wnloads ". Wenn ich nicht ' t hardcode it (wie unten) wird es jedes Mal weiter beschädigt, wenn ich die Spalteirheire die Größe habe.

So sieht es nach einer Paar -Größenänderung aus:Bildschirmfoto

Folgendes mache ich gerade.

  if (e.ColumnIndex == 1)
  {
    foreach (DataGridViewRow Row in mappingsDataGrid.Rows)
    {
      string Path = (string)Row.Cells[1].Value;
      Path = Path.Trim();

      TextRenderer.MeasureText(Path, e.CellStyle.Font,
        new Size(mappingsDataGrid.Columns[e.ColumnIndex].Width, Row.Height),
          TextFormatFlags.ModifyString | TextFormatFlags.PathEllipsis);

      e.Value = Path;
    }
  }

Das wird immer wieder seltsamer !!

Ich habe es geschafft, das Problem der verstümmelten Schnur zu beheben, indem ich jeden Char durchdrungen und die schlechten Entfernen entfernt habe. Jetzt habe ich jedoch ein noch verrückteres Problem. Eine lokale Variable, die ich im Ereignishandler zuweist, behält ihren Wert zwischen Anrufen bei.

Hier ist der entsprechende Code:

     string Path = ""; // <-- #1
     Path = "C:\\Documents and Settings\\jluce\\My Documents\\Downloads"; // <-- #2

      TextRenderer.MeasureText(Path, Row.Cells[1].Style.Font,
        new Size((mappingsDataGrid.Columns[e.Column.Index].Width), Row.Height),
          TextFormatFlags.ModifyString | TextFormatFlags.PathEllipsis);

      // Left out code that strips invalid chars

      Row.Cells[1].Value = Path; // <-- #3
      Path = null;

Die Spalte zum ersten Mal Größenänderung (siehe #in den Kommentaren oben):

  1. Nach diesem Zeilenweg enthält "" ".
  2. Nach diesem Zeilenpfad enthält die Zeichenfolge genau wie oben.
  3. Pfad enthält verkürzten Dateipfad wie er sollte (dh "C: Dokumente und Setti ... Downloads")

Zweite Mal die Größenänderung:

  1. Nach diesem Zeilenweg enthält "" "", wie es sollte.
  2. Nach diesem Zeilenweg enthält Pfad "C: Dokumente und Set ... Downloads 0 Dokumente Downloads", was der ungültige Wert aus der vorherigen Iteration war, bevor ich die ungültigen Zeichen (hier als ' 0') ausgezogen habe! !
  3. Jetzt ist der Pfad Fubar, weil ich mit einer verschraubten Schnur angefangen habe und es sich nur noch schlechter wird.

Warum sollte Pfad den ungültigen Wert aus dem vorherigen Funktionsaufruf (nach korrekter Zuweisung einer leeren Zeichenfolge!) Zugewiesen, wenn ich explizit einen Wert zuweisen? !!!!!

War es hilfreich?

Lösung

TextRenderer.MeasureText Methode ist a böse - Es ändert die tatsächliche Zeichenfolge als Parameter, sodass die tatsächliche Zeichenfolge, in der die DataGridView verwiesen wird, ändert. Es macht tatsächlich eine .NET -Zeichenfolge veränderlich.

Es scheint auch, dass diese lächerliche Methode die tatsächliche nicht ändert Length der Saite, aber lediglich einen der Charaktere mit überschreiben \0 um das Ende der Saite anzuzeigen (wie null-terminierte Zeichenfolgen in einfach c). Das sind ein paar lustige Sachen!

Dies kann ernsthafte Auswirkungen auf die Stabilität Ihrer App haben. Wenn Sie berücksichtigen, dass .NET verwendet Saitenquitt, Sie können anfangen, alle möglichen seltsamen Ergebnisse zu erzielen, wie Sie bemerkt haben, dass Ihre String -Konstanten nicht mehr konstant erscheinen.

Der erste Schritt besteht darin, eine Kopie Ihrer Zeichenfolge zu erstellen (eine neue Instanz mit denselben Zeichen):

string Path = String.Copy(e.Value as string ?? "");

Anstatt von

string Path = (string)Row.Cells[1].Value;

Dies wird sicherstellen, dass egal was passiert TextRenderer Der ursprüngliche String bleibt unverändert.

Danach müssen Sie den Null-Charakter in der modifizierten Zeichenfolge loswerden.

Auf diese Weise:

if (Path.IndexOf('\0') >= 0)
   e.Value = Path.Substring(0, Path.IndexOf('\0'));
else
   e.Value = Path;

Sie erstellen eine neue Instanz einer sauberen, modifizierten Zeichenfolge (vorübergehend lassen Path Kopieren Sie für die Müllsammlung nicht realisiert).

Andere Tipps

Sie müssen das CellFormating -Ereignis verwenden, um den angegebenen Wert zu ändern, bevor er gedruckt wird (der ursprüngliche Objektwert wird nicht geändert). In Ihrem Fall können Sie prüfen, ob es sich um die rechte Spalte handelt, indem Sie die Variable der E. columnIndex wie ich nach unten geändert haben:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.DataSource = new List<Person>(new Person[] { new Person() { Name = "André", Adress = "Brazil" } });
    }

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        e.Value = e.Value + " modified";
    }
}

class Person
{
    public String Name { get; set; }
    public String Adress { get; set; }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top