2013-11-15 4 views
3

Я хочу, чтобы выделенный элемент ListView оставался четко видимым, когда фокус потерян (он тусклый серый на Windows 7). Я установил свойство HideSelection в значение False.Переопределение события Drawitem в элементе управления ListView WinForm

Я хотел бы сделать для List View, что кто-то сделал здесь для управления TreeView, а именно, переопределить событие Drawnode:

C# WinForms highlight treenode when treeview doesnt have focus

Я полагаю, мне нужно установить свойство OwnerDraw в Правда переопределить событие DrawItem, но я не уверен, что мне нужно делать в этом случае .... :-)

ответ

6

Вам нужно что-то вроде этого:

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) 
{ 
    e.DrawDefault = true; 
} 

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) 
{ 
    const int TEXT_OFFSET = 1; // I don't know why the text is located at 1px to the right. Maybe it's only for me. 

    ListView listView = (ListView)sender; 

    // Check if e.Item is selected and the ListView has a focus. 
    if (!listView.Focused && e.Item.Selected) 
    { 
     Rectangle rowBounds = e.SubItem.Bounds; 
     Rectangle labelBounds = e.Item.GetBounds(ItemBoundsPortion.Label); 
     int leftMargin = labelBounds.Left - TEXT_OFFSET; 
     Rectangle bounds = new Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, e.ColumnIndex == 0 ? labelBounds.Width : (rowBounds.Width - leftMargin - TEXT_OFFSET), rowBounds.Height); 
     TextFormatFlags align; 
     switch (listView.Columns[e.ColumnIndex].TextAlign) 
     { 
      case HorizontalAlignment.Right: 
       align = TextFormatFlags.Right; 
       break; 
      case HorizontalAlignment.Center: 
       align = TextFormatFlags.HorizontalCenter; 
       break; 
      default: 
       align = TextFormatFlags.Left; 
       break; 
     } 
     TextRenderer.DrawText(e.Graphics, e.SubItem.Text, listView.Font, bounds, SystemColors.HighlightText, 
      align | TextFormatFlags.SingleLine | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis); 
    } 
    else 
     e.DrawDefault = true; 
} 

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e) 
{ 
    ListView listView = (ListView)sender; 

    // Check if e.Item is selected and the ListView has a focus. 
    if (!listView.Focused && e.Item.Selected) 
    { 
     Rectangle rowBounds = e.Bounds; 
     int leftMargin = e.Item.GetBounds(ItemBoundsPortion.Label).Left; 
     Rectangle bounds = new Rectangle(leftMargin, rowBounds.Top, rowBounds.Width - leftMargin, rowBounds.Height); 
     e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds); 
    } 
    else 
     e.DrawDefault = true; 
} 

EDIT: Улучшено для View = View.Details и FullRowSelect = true.
EDIT2: Учитываются различные типы выравнивания столбца, а также добавлен флаг автоэллипса.

+0

К сожалению, мой список содержит несколько столбцов, и текст исчезает для всех, кроме первого столбца, когда выбрана строка. Могу ли я наложить на вас также помощь в реализации метода подбора предметов? Я использую полный выбор строки. – ChadD

+0

Я обновил код для ваших нужд. Теперь все 3 события обрабатываются: 'DrawItem',' DrawSubItem', 'DrawColumnHeader'. – Dmitry

+0

Помимо незначительной проблемы, когда colimn недостаточно велик, чтобы отобразить полный текст и многоточие, он работал очень хорошо. Текст столбца fulkl переливался в следующий столбец. – ChadD

Смежные вопросы