Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET
Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij slevové akce 80% výuky zdarma!
birthday

Diskuze: ListView OwnerDraw, VirtualMode, View=Details

Aktivity (5)
Avatar
jt.e
Člen
Avatar
jt.e:30.12.2015 16:28

Zdravím, potřeboval bych pomoct s vykreslováním ListView.
Vytvořil jsem aplikaci ve které, jsem nejprve data zobrazoval v klasickém ListView, ale při přejení myší nad listem nepříjemně blikal, tak jsem na netu našel návod jak se toho blikání zbavit:

public partial class NiceList : ListView
{
    private const int WM_ERASEBKGND = 0x0014;

    public NiceList()
    {
        InitializeComponent();
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.EnableNotifyMessage, true);
        DoubleBuffered = true;
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
    /// <summary>
    /// Notifies the control of Windows messages.
    /// </summary>
    /// <param name="m">A System.Windows.Forms.Message that represents the Windows message.
    protected override void OnNotifyMessage(Message m)
    {
        if (m.Msg != WM_ERASEBKGND)
            base.OnNotifyMessage(m);
    }
}

teď to sice nebliká, ale při najetí myší na položku někdy mizí text

vykreslování položek mám takto:

private void lvLst_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    SolidBrush brush_back = new SolidBrush(color_back);
    SolidBrush brush_fore = new SolidBrush(color_fore);
    StringFormat sformat = new StringFormat(StringFormatFlags.NoWrap);

    e.Graphics.FillRectangle(brush_back, e.SubItem.Bounds);
    e.Graphics.DrawString(e.SubItem.Text, lvLst.Font, brush_fore, e.SubItem.Bounds, sformat);
}
Editováno 30.12.2015 16:30
 
Odpovědět
30.12.2015 16:28
Avatar
jt.e
Člen
Avatar
jt.e:31.12.2015 10:57

Ještě musím dodat, že mám nastaveno FullRowSelect=tru­e.
A mizení textu se projevuje pouze u SubItems, 1. sloupec funguje dobře;

 
Nahoru Odpovědět
31.12.2015 10:57
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
jt.e
Člen
Avatar
jt.e:1.1.2016 22:37

Tak už jsem na to přišel.

Tady je kód zkušební aplikace:

public partial class Form1 : Form
{
    public static readonly Color clDefault1 = Color.FromArgb(20, 20, 20);
    public static readonly Color clDefault2 = Color.FromArgb(16, 16, 16);
    public static readonly Color clSelected = Color.FromArgb(36, 36, 56);
    public static readonly Color clActived = Color.MidnightBlue;

    private List<int> lst = new List<int>();

    public Form1()
    {
        InitializeComponent();
        lvLst.BackColor = clDefault2;
        lst = new List<int>();

        Random ran = new Random();
        while (lst.Count < 1000) lst.Add(ran.Next(1, int.MaxValue));
        lvLst.VirtualListSize = lst.Count;
    }
    //(lvLst je ListView)
    private void lvLst_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
    {
        e.DrawDefault = true;
    }

    private void lvLst_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
    {
        int r = e.ItemIndex + 1;

        ListViewItem lvi = new ListViewItem();

        lvi.Text = r.ToString();
        lvi.ForeColor = Color.White;
        lvi.BackColor = ((e.ItemIndex & 0x00000001) == 0x00000001) ? clDefault1 : clDefault2;

        lvi.SubItems.Add(DateTime.Now.ToLongTimeString(), Color.YellowGreen, lvi.BackColor, lvLst.Font);

        lvi.SubItems.Add(lst[e.ItemIndex].ToString("X8"),
                        (lst[e.ItemIndex] > 0x40404040) ? Color.DodgerBlue : Color.DeepSkyBlue,
                        lvi.BackColor, lvLst.Font);


        e.Item = lvi;
    }

    private void lvLst_DrawItem(object sender, DrawListViewItemEventArgs e)
    {
        Color color_back = e.Item.BackColor;
        if (lvLst.SelectedIndices.Count > 0)
        {
            if (lvLst.SelectedIndices[0] == e.ItemIndex) color_back = clActived;
            else if (e.Item.Selected) color_back = clSelected;
        }

        SolidBrush brush_back = new SolidBrush(color_back);
        e.Graphics.FillRectangle(brush_back, e.Item.Bounds);

        SolidBrush brush_fore = new SolidBrush(e.Item.ForeColor);
        e.Graphics.DrawString(e.Item.Text, lvLst.Font, brush_fore, e.Item.Bounds);

        for(int i=1; i<e.Item.SubItems.Count; i++)
        {
            SolidBrush brush = new SolidBrush(e.Item.SubItems[i].ForeColor);
            e.Graphics.DrawString(e.Item.SubItems[i].Text, lvLst.Font, brush, e.Item.SubItems[i].Bounds);
        }
    }
}

součástí je i tento kód upravené komponenty ListView:

public partial class NiceList : ListView
{
    private const int WM_ERASEBKGND = 0x0014;

    public NiceList()
    {
        InitializeComponent();
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
    /// <summary>
    /// Notifies the control of Windows messages.
    /// </summary>
    /// <param name="m">A System.Windows.Forms.Message that represents the Windows message.
    protected override void OnNotifyMessage(Message m)
    {
        if (m.Msg != WM_ERASEBKGND)
            base.OnNotifyMessage(m);
    }
}
Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět
1.1.2016 22:37
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.