Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > ListView


Автор: zss 30.11.2006, 20:43
не хотел задавать вопрос в соседней теме 

1. можно ли сделать нужную колонку авторасширяемой ? и как ограничить минимальный размер - формой ?
2. есть поток, который обрабатывает данные и где-то раз в секунду отрисовывает их.
Старые данные удаляются. а новые отрисовываются. Так вот происходит сильное мерцание
Ни SuspendLayout ни BeginUpdate не помагают. как можно ускорить отрисовку ? 

Автор: ivashkanet 30.11.2006, 20:51
Цитата(zss @  30.11.2006,  19:43 Найти цитируемый пост)
Ни SuspendLayout ни BeginUpdate не помагают. как можно ускорить отрисовку ?  

DoubleBufered = true у формы  smile 

Автор: zss 30.11.2006, 20:53
Цитата(ivashkanet @  30.11.2006,  20:51 Найти цитируемый пост)
DoubleBufered = true у формы 

поставил в первую очередь smile

Автор: mr.DUDA 1.12.2006, 12:36
Рисуем на чём ? Если не прямо на форме, а на панели или другом контроле - то DoubleBuffered не поможет, надо в классе контрола написать:

Код
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.ResizeRedraw = true;

Автор: zss 1.12.2006, 19:19
Цитата(mr.DUDA @  1.12.2006,  12:36 Найти цитируемый пост)
Рисуем на чём ?

да ни на чем smile просто заполняю список

Цитата(mr.DUDA @  1.12.2006,  12:36 Найти цитируемый пост)
Если не прямо на форме, а на панели или другом контроле - то DoubleBuffered не поможет, надо в классе контрола написать:


Цитата(mr.DUDA @  1.12.2006,  12:36 Найти цитируемый пост)
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.ResizeRedraw = true;

это что за чудо - и что оно даст ?

Добавлено @ 19:24 
и у какого контрола это нужно если я не наследуюсь от ListView

Можно например у формы ?

Автор: DarkDragon 1.12.2006, 21:07
ControlStyles.OptimizedDoubleBuffer - это вроде как я понял оптимизированный двойной буфер.
ControlStyles.AllPaintingInWmPaint - Это короче вся отрисовка в сообщении WmPaint(вроде в WndProc метода у контрола)

в совокупности дает немерцающее обновление (методом Refresh или Invalidate)

Цитата(zss @  1.12.2006,  19:19 Найти цитируемый пост)
и у какого контрола это нужно если я не наследуюсь от ListView

На panel, control, usercontrol

Цитата(zss @  1.12.2006,  19:19 Найти цитируемый пост)
Можно например у формы ? 

Да.

Автор: zss 1.12.2006, 22:29
Цитата(DarkDragon @  1.12.2006,  21:07 Найти цитируемый пост)
Можно например у формы ? 


Да. 

ну... в самом деле сильно не помогло smile

еще я заметил некую странность - например просто при расширении формы происходит такой сильный затуп,
что все больше и больше возникает желание отказаться от .NET и перейти на старый и проверенный Builder C++ smile

Автор: Naum 2.12.2006, 09:48
Цитата(zss @  1.12.2006,  23:29 Найти цитируемый пост)
ну... в самом деле сильно не помогло 


Цитата(mr.DUDA @  1.12.2006,  13:36 Найти цитируемый пост)
Рисуем на чём ? Если не прямо на форме, а на панели или другом контроле - то DoubleBuffered не поможет, надо в классе контрола написать:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.ResizeRedraw = true;


Автор: mr.DUDA 2.12.2006, 14:01
Цитата(zss @  1.12.2006,  21:29 Найти цитируемый пост)
ну... в самом деле сильно не помогло

ListView сделан на стандартном элементе управления Windows, поэтому новые фишки как двойная буферизация, не поддерживает. И переход на билдер не спасёт, если там тот же листвью используется (завёрнут в VCL). 

Побороть мерцание можно так:
1) для добавления нескольких строк в листвью, вместо Add использовать AddRange
2) или запрещать отрисовку на время добавления строк:

ListViewEx.cs
Код
using System;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public class ListViewEx : ListView
    {
        public bool EnablePaint = true;

        const int WM_PAINT = 0x000F;
        const int WM_ERASEBKGND = 0x0014;

        protected override void WndProc(ref Message m)
        {
            if (!EnablePaint && (m.Msg == WM_PAINT || m.Msg == WM_ERASEBKGND))
            {
                m.Result = IntPtr.Zero;
                return;
            }

            base.WndProc(ref m);
        }
    }
}


Form1.cs
Код
using System;
using System.Windows.Forms;

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

        private void timer1_Tick(object sender, EventArgs e)
        {
            listViewEx1.EnablePaint = false;
            listViewEx1.Items.Clear();
            for (int i = 0; i < 500; i++)
                listViewEx1.Items.Add(i.ToString());
            listViewEx1.EnablePaint = true;
        }
    }
}

Автор: zss 3.12.2006, 16:45
mr.DUDA, а как правильно создавать этот класс. как класс или как компонент ?

Если как компонент - то как унаследоваться от существующего, чтоб он был виден в ToolBox?
З.Ы. Пока еще не создавал компоненты smile

Автор: mr.DUDA 3.12.2006, 19:07
Цитата(zss @  3.12.2006,  15:45 Найти цитируемый пост)
 как правильно создавать этот класс. как класс или как компонент ?

Как угодно. В любом случае сам на тулбокс попадёт smile.

Автор: zss 3.12.2006, 19:08
Цитата(mr.DUDA @  3.12.2006,  19:07 Найти цитируемый пост)
В любом случае сам на тулбокс попадёт

это как-это ?

Автор: mr.DUDA 3.12.2006, 19:10
Цитата(zss @  3.12.2006,  18:08 Найти цитируемый пост)
это как-это ?

При компиляции.

Автор: zss 3.12.2006, 22:42
mr.DUDA, вроде мерцание победил - спасибо

только появилась еще проблемма.

Есть 2 ListView. Они отображают иерархию. Тоесть например

Код

class A;
class B
{
    string name;
    int count;
    List<A> list;
}


тоесть в первом ListView отображается классы В.
Если щелкнуть на ListViewItem, то во втором должен отобразиться список классов А для него, но

1. Список 1 постоянно обновляется и теряет выделение (тоесть он сначала очищается, а потом заново заполняется
т.к. может меняться). Как можно сохранить выделение?
2. У списка 2 в Tag храниться выбранный класс В из 1 списка. Хотелось бы при изменении самого В, чтоб
автоматически менялся и список А (тоесть обновлялся). Как это правильно сделать?
3. Как вообще сказать списку обновиться (например чтоб отработал какой-нибудь его метод)?

Тоесть хотелось бы завязать както  оба ListView на данные. Может с помощью вспомогательного компонента.

Автор: mr.DUDA 3.12.2006, 23:08
По идее, любой контрол можно замапить на источник данных (DataSet, коллекцию объектов etc.), но это не относится к ListView. Придётся всё делать вручную

1. Запоминать выделенный элемент по какому-л. признаку (значение в Tag, etc.) и ставить фокус на него после обновления. Если кол-во элементов не меняется, можно попробовать поиграться с позицией прокрутки (восстанавливать её в то же значение)
2. Обрабатывать события изменения айтема; или я что-то не так понял?
3. Update, Refresh

Автор: zss 3.12.2006, 23:11
Цитата(mr.DUDA @  3.12.2006,  23:08 Найти цитируемый пост)
По идее, любой контрол можно замапить на источник данных (DataSet, коллекцию объектов etc.), но это не относится к ListView. Придётся всё делать вручную

а есть где-нибудь статейка по DataSet ?

Что-то мне кажется он меня спасет smile

Автор: thomas 3.12.2006, 23:17
zss, 
Цитата

а есть где-нибудь статейка по DataSet ?


посмотри http://msdn.microsoft.com/library/rus/default.asp?url=/library/RUS/vbcon/html/vboriCodeExamplesForDataAccess.asp  smile  и http://msdn.microsoft.com/library/rus/default.asp?url=/library/RUS/dv_vbCode/html/vboriCreatingFillingDatasetExampleTopics.asp

Автор: zss 6.12.2006, 19:55
Цитата(mr.DUDA @  3.12.2006,  23:08 Найти цитируемый пост)
Запоминать выделенный элемент по какому-л. признаку (значение в Tag, etc.) и ставить фокус на него после обновления

сделал чтоб выделения сохранялись. но есть все-равно косяк.
метод который вызывается из отдельного потока и метод который запоминает выделение по щелчку мыши не дружат между собой.
тоесть когда я щелкаю может происходить обновление и оно сразу снимается. приходится иногда по несколько раз щелкать. lock(this) не помагает.
как можно правильно это синхронизировать чтоб при любых действиях пользователя списки не обновлялись ? 

Автор: zss 10.12.2006, 18:38
Цитата(zss @  30.11.2006,  20:43 Найти цитируемый пост)
1. можно ли сделать нужную колонку авторасширяемой ? и как ограничить минимальный размер - формой ?

очень нужен ртвет на этот вопрос smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)