Frage

Ist es möglich, den gesamten Spalte Kopfbereich einer Listenansicht auf OwnerDraw? (Einschließlich der Region auf der rechten Seite der Spaltenüberschriften)? Listview ist in der Detailansicht.

Eine Antwort zeigt hier, dass der verbleibende Raum kann zusammen mit dem letzten Spaltenüberschrift ziehen: http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.windowsforms/topic32927.aspx

Aber es scheint nicht, überhaupt zu arbeiten -. Nichts außerhalb Kopfbereich gezogen wird,

Die vorgeschlagene Lösung basiert außerhalb der übergebenen Bounds auf Zeichnung:

if (e.ColumnIndex == 3) //last column index
{
    Rectangle rc = new Rectangle(e.Bounds.Right, //Right instead of Left - offsets the rectangle
            e.Bounds.Top, 
            e.Bounds.Width, 
            e.Bounds.Height);

    e.Graphics.FillRectangle(Brushes.Red, rc);
}

Die ClipBounds Eigenschaft des verfügbaren Grafik Beispiels zeigt einen ungebundenen Bereich (von großen negativen Zahlen zu groß positiv). Aber nichts ist außerhalb des Column Bereich der letzten Spalte gezogen.

Hat jemand eine Lösung für dieses?

War es hilfreich?

Lösung

Ich bin von Jeffery Tan Antwort in diesem Beitrag überrascht. Seine Lösung kann nicht funktionieren, da der Code versucht, außerhalb des Kopfsteuer Client-Bereichs zu ziehen. Die hDC in benutzerdefinierter Zeichnung verwendet (und somit Zeichnung Besitzer) für den Client-Bereich der Steuerung, und kann somit nicht in dem Nicht-Client-Bereich malen verwendet werden. Der Bereich rechts von der am weitesten rechts stehenden Spalte in einer Header-Steuerung ist in nicht-Client-Bereich. Sie müssen also eine andere Lösung.

Mögliche Lösungen

  1. Hallo-Tech und teilweise wirksam

Sie können außerhalb des Client-Bereichs ermöglichen Zeichnung durch den GetDC() WinAPI-Aufruf:

[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr GetDC(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);

public static IntPtr GetHeaderControl(ListView list) {
    const int LVM_GETHEADER = 0x1000 + 31;
    return SendMessage(list.Handle, LVM_GETHEADER, 0, 0);
}

In Ihrer Spalte Draw Event-Handler, werden Sie so etwas wie dieses brauchen:

if (e.ColumnIndex == 3) //last column index
{
  ListView lv = e.Header.ListView;
  IntPtr headerControl = NativeMethods.GetHeaderControl(lv);
  IntPtr hdc = GetDC(headerControl);
  Graphics g = Graphics.FromHdc(hdc);

  // Do your extra drawing here
  Rectangle rc = new Rectangle(e.Bounds.Right, //Right instead of Left - offsets the rectangle
            e.Bounds.Top, 
            e.Bounds.Width, 
            e.Bounds.Height);

    e.Graphics.FillRectangle(Brushes.Red, rc);

  g.Dispose();
  ReleaseDC(headerControl, hdc);
}

Aber das Problem dabei ist, dass seit der Zeichnung außerhalb des Client-Bereichs ist, wird Windows nicht immer wissen, wann es gezeichnet werden soll. So wird es manchmal verschwinden und dann neu gezeichnet werden, wenn Windows die Header-Anforderungen neu zu streichen denkt.

  1. Low-Tech, aber hässlich

Fügen Sie eine zusätzliche leere Spalte zu Ihrer Kontrolle, Eigentümer ziehen es aber suchen Sie wollen, machen es sehr breit, und schalten Sie den horizontalen Bildlauf (optional).

Ich weiß, das ist schrecklich, aber Sie suchen Anregungen:)

  1. Die meisten wirksam, aber noch nicht perfekt

Verwenden Sie Object . Dieser Wrapper um eine .NET-Listview kann Sie Overlays Ihre Liste hinzufügen - ein Overlay überall innerhalb des Listview ziehen, einschließlich der Kopfzeile. [Erklärung: Ich bin der Autor von Object, aber ich finde es immer noch beste Lösung ist]

public class HeaderOverlay : AbstractOverlay
{
    public override void Draw(ObjectListView olv, Graphics g, Rectangle r) {
        if (olv.View != System.Windows.Forms.View.Details)
            return;

        Point sides = NativeMethods.GetColumnSides(olv, olv.Columns.Count-1);
        if (sides.X == -1)
            return;

        RectangleF headerBounds = new RectangleF(sides.Y, 0, r.Right - sides.Y, 20);
        g.FillRectangle(Brushes.Red, headerBounds);
        StringFormat sf = new StringFormat();
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Center;
        g.DrawString("In non-client area!", new Font("Tahoma", 9), Brushes.Black, headerBounds, sf);
    }
}

Dies ergibt dies: alt text

[über diese Antwort Lesen, ich denke, dies ist ein Beispiel zu hart zu versuchen :) Hoffe, dass Sie etwas hier hilfreich.]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top