Problém při překreslování komponenty s OwnerDraw   zodpovězená otázka

VB.NET, Komponenty, .NET

Ahoj, mám problém při překreslování ColumnHeader u ListView. Používám tenhle kód:

    Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
        e.DrawDefault = True

        If e.ColumnIndex = 0 Then
            Dim x As Integer = e.Bounds.X + e.Bounds.Width - 20

            Dim Asc As Point() = {New Point(x, 11), New Point(x + 10, 11), New Point(x + 5, 5)}
            Dim Desc As Point() = {New Point(x, 6), New Point(x + 10, 6), New Point(x + 5, 11)}

            Dim dic As New Dictionary(Of Integer, Point())
            dic.Add(0, Asc)
            dic.Add(1, Desc)

            e.Graphics.FillPolygon(Brushes.DimGray, dic(ListView1.Sorting))
        End If
    End Sub

problém je v tom, že se mi to nepřekreslí... teda ono se to vykreslí, když zapoznámkuju první příkaz e.DrawDefault = True, tak je to vidět. Úplně navrch se to vykreslí jen když dám za x hodnotu na tvrdo a nevypočítávám jí z e.Bounds. Nevíte někdo čím to je a jak se toho zbavit?

Za všechny postřehy předem děkuju

nahlásit spamnahlásit spam 0 odpovědětodpovědět

opravdu mi nikdo nedokážete poradit, co dělám špatně?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Co děláte špatně, že nikdo neporadí? Zkuste napsat co sledujete, zájmena ono a to nahraďte podstatnými jmény... Upřesněte: "Úplně navrch se to vykreslí"... Napište kolik máte sloupců, čím má být událost "ListView1_DrawColumnHeader" vyvolána (od čeho ji očekáváte), jak měníte třídění, jak máte nastavené "OwnerDeaw" při spuštění aplikace.

Berte v úvahu, že

- událost "ListView1_DrawColumnHeader" nenastane při nastavení "OwnerDeaw=False"

- "e.DrawDefault = True" potlačí nastavení "OwnerDeaw=True"

- "ListView1.Sorting" má hodnoty

-- 0 pro None - - používáte pro Ascending !!!

-- 1 pro Ascending - - používáte pro Descending !!!

-- 2 pro Descending - - nemáte ošetřené !!!

nahlásit spamnahlásit spam 0 odpovědětodpovědět

OwnerDraw je při startu nastaveno na True. Sloupce mám 4. Předpokládám, že ListView1_DrawColumnHeader se provádí při každým překreslení a myslím si, že změna prvků vyvolá překreslení celý komponenty. Tím vykreslením úplně na vrch jsem myslel, že se vykreslí systemový styl a přes to vykreslím něco já. ještě doplním, že pro třídění používám třídu ListViewItemComparer http://vbnet.cz/forum-tema--1475-upraven...

tady je celý kód:

Public Class Form1

    Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
        Dim itemSorter = DirectCast(ListView1.ListViewItemSorter, ListViewItemComparer)
        itemSorter.Column = e.Column
        itemSorter.SortOrder *= -1
        ListView1.Sort()
        ListView1.Refresh()
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ListView1.ListViewItemSorter = New ListViewItemComparer(0)
    End Sub

    Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
        e.DrawDefault = True

        Dim sorter As ListViewItemComparer = ListView1.ListViewItemSorter

        If sorter.SortOrder = 0 Then Exit Sub

        Dim colWidth As Integer = -20
        For i As Integer = 0 To sorter.Column
            colWidth += ListView1.Columns(i).Width
        Next

        Dim Asc As Point() = {New Point(colWidth, 11), New Point(colWidth + 10, 11), New Point(colWidth + 5, 5)}
        Dim Desc As Point() = {New Point(colWidth, 6), New Point(colWidth + 10, 6), New Point(colWidth + 5, 11)}

        Dim dic As New Dictionary(Of Integer, Point())
        dic.Add(-1, Desc)
        dic.Add(1, Asc)

        e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        e.Graphics.FillPolygon(Brushes.DimGray, dic(sorter.SortOrder))
    End Sub

    Private Sub ListView1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
        e.DrawDefault = True
    End Sub

    Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
        e.DrawDefault = True
    End Sub
End Class

Můžete si vyzkoušet, že takhle to funguje, ALE... nevím proč, v posledním sloupci se prostě nevykreslí. A myslím že je tady ještě jedno ale, předpokládám, že při refreshi se překreslí hlavičky všech sloupců, takže se při každém překreslení vykreslí 4x do jednoho místa. Když jsem to chtěl omezit jen na jeden sloupec a dal jsem za e.DrawDefault = True tuhle podmínku, tak se nevykreslí už vůbec nic

        If e.ColumnIndex <> sorter.Column Then Exit Sub

nahlásit spamnahlásit spam 0 odpovědětodpovědět

V "ListView1_DrawColumnHeader" odstraňte "e.DrawDefault = True", aby se nerušilo nastavení "OwnerDeaw=True"!

A před vaše vlastní vykreslení nechte vykreslit hlavičky sloupců, jak to uvádí p. Linhart v

http://www.vbnet.cz/forum-tema--817-sort...

    'Vykreslit standardní pozadí
    e.DrawBackground()
    'Vykreslit standardní text
    e.DrawText()
    ' vaše vykreslení
    e.Graphics.FillPolygon(Brushes.DimGray, dic(sorter.SortOrder))

pak to musí fungovat.

Pokud byste vložil:

If e.ColumnIndex <> sorter.Column Then Exit Sub

vykreslí se pouze hlavička aktuálního sloupce.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

no, když mě šlo o to, jestli to jde překreslovat přes systémovej styl, se zachováním všech efektů...

    e.DrawBackground()
    e.DrawText()

tohle už vypadá nestandartně

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkusil jsem to (VB .NET 2005 express, Windows XP Prof.). Vzhled se mi mění jen ve změně barvy textu v záhlaví sloupce při najetí myší. Jinak se ke standardnímu vzhledu přidá šipka a jiný rozdíl nevidím.

V čem máte rozdíl, co chybí?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A používáte vizuální styly WinXP? Pořádně se na to podívejte, zdá se Vám, že se to chová stejně? Já bych chtěl právě dosáhnout toho, aby to používalo styl, kterej má nastavenej uživatel + aby se tam vykreslila ta šipka.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Styl nestyl - pořád to funguje!

http://bayer.wz.cz/xp_styly.jpg

Příčinu tedy musíte najít u sebe. Co na jiném počítači?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

sakra jak to, že ten rozdíl nevidíte? U většiny stylů, když najedete myší na hlavičku sloupce, tak má daleko zajímavější efekt než je změna barvy textu... Když to udělám, tak jak Vy říkáte, tak ANO bude na první pohled vypadat téměř stejně, ale rozhodně se tak nebude chovat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Sakra, měl jsem snahu vám pomoct a tak mi vynadejte! Pletete si vykreslení (o ničem jiném jste nepsal!) s efekty a přehlížíte, že ListView není složka.

Po efektech nepasu, naopak zbytečné vypínám. Počítač mám na práci, potěšení hledám jinde. Stěžujte si u Microsoftu. Já jsem s jeho produkty, které mi dal zadarmo, spokojený.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

... a jeden sloupec navíc se šířkou nula, protože poslednímu sloupci default vykreslení šipku smaže

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Omlouvám se za výpad, asi mě podráždilo to "sakra" a fakt, že jste řešil zejména překreslování. Efekty mě unikly, zkoušku jsem totiž udělal hned tak, jak to máte nyní a nevěděl, že ListView umí to, co složka

Na usmířenou tu máte řešení - místo postupného vykreslování s e.DrawBackground() a e.DrawText() dejte:

e.DrawDefault = True

a záhlaví sloupců má všechny efekty i šipku

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já se Vám taky omlouvám, nějak jsem se neudržel. Děkuju Vám za snahu, s jakou jste to tady se mnou řešil. To poslední řešení je stejný jako to co jsem použil ve svým projektu ještě než jsem se na to zeptal... ale prostě připadalo mi takový nějaký kostrbatý. Takže ještě jednou děkuju a už to nebudeme dál řešit

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback