Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дёргание TreeView, при добавлении, удалении нодов 
:(
    Опции темы
маерсон
Дата 12.2.2009, 05:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



Есть Node1(содержит в себе Child1, Child2, Child3) и Node2(содержит в себе Child4, Child5, Child6). Отрисовываются вручную в OwnerDrawAll. Программа по задумке периодически из Node2 удаляет один из Child'ов и сразу добавляет в Node1, таким образом перемещение чаилдов. Но когда происходит удаление и добавление(оба родительских нода развернуты всегда), TreeView дергается-мерцает. 
Пробовал перед удалением делать 
Код

BeginUpdate
 
и 
Код

EndUpdate 

после удаления нода - все равно мигает. Пробовал также и так:
Код

child.Remove();                      
TreeView.BeginUpdate();
TreeView.Nodes[0].Nodes.Add("Child #");
TreeView.EndUpdate();

Все равно дергается. Как бороться?

Это сообщение отредактировал(а) маерсон - 12.2.2009, 16:28
PM MAIL   Вверх
Partizan
Дата 12.2.2009, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



маерсон, что значит дёргается? родительский узел сворачивается/разворачивается?


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
маерсон
Дата 12.2.2009, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



не совсем так: мерцание дерева и при сворачивании\разворачивании наблюдается. Также мерцает при ресайзе.

Это сообщение отредактировал(а) маерсон - 12.2.2009, 16:25
PM MAIL   Вверх
unicuum
Дата 12.2.2009, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 830
Регистрация: 16.3.2005
Где: Рашка

Репутация: 1
Всего: 8



Цитата(маерсон @  12.2.2009,  05:51 Найти цитируемый пост)
Все равно дергается. Как бороться?

Если child это нод, и принадлежит TreeView, попробуй так.

Код
TreeView.BeginUpdate();
child.Remove();
TreeView.Nodes[0].Nodes.Add("Child #");
TreeView.EndUpdate();



--------------------
user posted image
обычный день на винграде
PM   Вверх
маерсон
Дата 13.2.2009, 05:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



unicuum, тоже пробовал - моргает все равно при отрисовке.

Читал про свойство DoubleBuffer, возможно сумеет убрать моргание...но до него добраться можно, если наследовать от TreeView...правда не смог нормально реализовать и отобразить данные в дереве(вернее данные вообще перестали отображаться), хотя просто делал так:
Код

public class XtreeView : TreeView
{
     public XtreeView()
     {
          this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
     }
}


Это сообщение отредактировал(а) маерсон - 13.2.2009, 08:00
PM MAIL   Вверх
TIGERоX
Дата 13.2.2009, 13:27 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


начинающий...
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 7.9.2005

Репутация: нет
Всего: 1



 this.SetStyle(ControlStyles.DoubleBuffer, true);
хватит этого, остальные флаги говорят о том что пользователь на себя берет отрисовку контрола
PM MAIL   Вверх
маерсон
Дата 13.2.2009, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



TIGERоX, уже испробывал - все равно моргает!
PM MAIL   Вверх
маерсон
Дата 13.2.2009, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



Раз уж никто не сталкивался с такой аномалией, может посоветуете достойную аналогию TreeView?
PM MAIL   Вверх
Любитель
Дата 13.2.2009, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: нет
Всего: 92



Если отрисовываешь вручную - и рисуешь дерево целиком, переопредели OnPaintBackground и ничего в нём не делай (не вызывай базовый обработчик).


--------------------
PM MAIL ICQ Skype   Вверх
TIGERоX
Дата 14.2.2009, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


начинающий...
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 7.9.2005

Репутация: нет
Всего: 1



покажите пожалуйста весь код
PM MAIL   Вверх
маерсон
Дата 14.2.2009, 04:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



Код

    public class XTreeView : TreeView
    {
        public XTreeView()
        {
            SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
        }

        protected virtual void OnPaintBackground(PaintEventArgs pevent)
        {
            //
            // huh?
            //
        }

        protected virtual void OnPaint(PaintEventArgs e)
        {
            //
            base.OnPaint(e);
            //
        }
    }


А как тогда background image отрисовать?

Это сообщение отредактировал(а) маерсон - 14.2.2009, 11:43
PM MAIL   Вверх
unicuum
  Дата 14.2.2009, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 830
Регистрация: 16.3.2005
Где: Рашка

Репутация: 1
Всего: 8



Цитата(маерсон @  13.2.2009,  05:40 Найти цитируемый пост)
unicuum, тоже пробовал - моргает все равно при отрисовке.

Значит ты не правильно перерисовываешь экран.

Цитата(маерсон @  13.2.2009,  20:07 Найти цитируемый пост)
Раз уж никто не сталкивался с такой аномалией, может посоветуете достойную аналогию TreeView? 

Лучше прочитай по этой теме какие-нибудь книжки, навроде "Коннелл Джон - Разработка элементов управления Microsoft .NET на Microsoft Visual Basic .NET" и прочее. Как правильно перерисовывать естественно без моргания ещё написано в MSDN.




--------------------
user posted image
обычный день на винграде
PM   Вверх
маерсон
Дата 15.2.2009, 06:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 9.2.2009

Репутация: нет
Всего: нет



unicuum, спасибо, в мсдн почитал. Теперь отрисовывается вручную все в собтии OnPaint. Каждый Node рисую если он видим, но как быть с фоном? 
Предполагаю, что вот так:
Код

private void myTreeView1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Image img = new Bitmap("123.bmp");
            g.DrawImageUnscaled(img, ClientRectangle);
            //...
            //...
            //...
            // Рисуются ноды
            //...
            //...
            //...
            //...
            myTreeView1.Invalidate(); // кушает здесь много от процессора
        }

Верно ли писать в OnPaint myTreeView1.Invalidate() ?
И что лучше использовать g.DrawImageUnscaled(img, g.VisibleClipBounds) или g.DrawImageUnscaled(img, ClientRectangle) ?

Как можно отрисовать тогда фон, если он стирается и видно как он перерисовывается?

Это сообщение отредактировал(а) маерсон - 15.2.2009, 17:00
PM MAIL   Вверх
Любитель
Дата 15.2.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: нет
Всего: 92



Цитата(маерсон @  15.2.2009,  06:12 Найти цитируемый пост)
myTreeView1.Invalidate()

Нет, конечно - в OnPaint-е этого нельзя писать.

Для фона переопределяй метод OnPaintBackground, как я уже писал. Само собой лучше перерисовать только видимую часть.


--------------------
PM MAIL ICQ Skype   Вверх
unicuum
  Дата 27.3.2009, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 830
Регистрация: 16.3.2005
Где: Рашка

Репутация: 1
Всего: 8



Попробовал тут реализовать этот функционал. В общем, тут надо разбираться в виндовых событиях, а я не разбираюсь.

Код
using System;
using System.Drawing;
using System.Windows.Forms;

namespace TreeViewImage
{
    /// <summary>
    /// Расширенный древовидный вид.
    /// </summary>
    public class ExtensionView : TreeView
    {
        /// <summary>
        /// Фоновое изображение.
        /// </summary>
        Image _backgroundImage;

        /// <summary>
        /// Прямоугольник (координаты и размер) фонового изображения.
        /// </summary>
        Rectangle _imageRectangle;

        /// <summary>
        /// Конструктор по умолчанию.
        /// </summary>
        public ExtensionView() : base()
        {
            PresetStyle();
        }

        /// <summary>
        /// Конструктор со значением.
        /// </summary>
        public ExtensionView(Image backImage) : this()
        {
            PresetStyle();
            BackImage = backImage;
        }

        /// <summary>
        /// Предустановка стилей.
        /// </summary>
        private void PresetStyle()
        {
            base.SetStyle(ControlStyles.DoubleBuffer, true);
            base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        }

        /// <summary>
        /// Фоновое изображение.
        /// </summary>
        public Image BackImage
        {
            get
            {
                return _backgroundImage;
            }
            set
            {
                if (value != null)
                {
                    _backgroundImage = value;
                    _imageRectangle.Width = _backgroundImage.Width;
                    _imageRectangle.Height = _backgroundImage.Height;

                    this.Invalidate();
                }
                else
                    throw new NullReferenceException();
            }
        }

        /// <summary>
        /// Происходит при перерисовке заднего фона.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            e.Graphics.DrawImage(BackImage, _imageRectangle);
        }

        /// <summary>
        /// Происходит до сворачивания.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnBeforeCollapse(TreeViewCancelEventArgs e)
        {
            base.OnBeforeCollapse(e);
            //this.Invalidate(_imageRectangle);
            this.Invalidate();
        }

        /// <summary>
        /// Происходит до разворачивания.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
        {
            base.OnBeforeExpand(e);
            this.Invalidate(_imageRectangle);
        }

        /// <summary>
        /// Происходит при изменение размера.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnResize(EventArgs e)
        {
            _imageRectangle.X = this.Width - BackImage.Width;
            _imageRectangle.Y = this.Height - BackImage.Size.Height;
            this.Invalidate();
        }

        /// <summary>
        /// Стереть задний фон.
        /// </summary>
        private const int WM_ERASEBKGND = 0x00000014;

        /// <summary>
        /// Перерисовывать узлы автоматически, а задний фон самим.
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            switch(m.Msg)
            {
                case WM_ERASEBKGND:
                    bool styleUserPaint = this.GetStyle(ControlStyles.UserPaint);
                    bool styleAllPainting =     this.GetStyle(ControlStyles.AllPaintingInWmPaint);
                    this.SetStyle(ControlStyles.UserPaint, true);
                    this.SetStyle(ControlStyles.AllPaintingInWmPaint, false);
                    base.WndProc(ref m);
                    this.SetStyle(ControlStyles.UserPaint, styleUserPaint);
                    this.SetStyle(ControlStyles.AllPaintingInWmPaint, styleAllPainting);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }

        /// <summary>
        /// Горизонтальная прокрутка.
        /// </summary>
        private const int WS_HSCROLL = 0x00100000;

        /// <summary>
        /// Убираем горизонтальную прокрутку.
        /// </summary>
        protected override CreateParams CreateParams 
        {
            get 
            {
                CreateParams parameters = base.CreateParams;
                parameters.Style |= WS_HSCROLL;
                return parameters;
            }
        }
    }
}


Надо что-то делать с событием сворачивания и разворачивания. Может заменить их на "после сворачивания и разворачивания". Тут дело даже не в том, что нельзя сделать нормально, просто надо тратить на это время, а майкрософт потом возьмёт и всё изменит и вообще сделает всё несовместимым.

user posted image
См. прикреплённый пример.

Это сообщение отредактировал(а) unicuum - 27.3.2009, 17:44

Присоединённый файл ( Кол-во скачиваний: 15 )
Присоединённый файл  TreeViewImage.rar 326,95 Kb


--------------------
user posted image
обычный день на винграде
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.1697 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.