Попробовал тут реализовать этот функционал. В общем, тут надо разбираться в виндовых событиях, а я не разбираюсь.
Код | 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; } } } } |
Надо что-то делать с событием сворачивания и разворачивания. Может заменить их на "после сворачивания и разворачивания". Тут дело даже не в том, что нельзя сделать нормально, просто надо тратить на это время, а майкрософт потом возьмёт и всё изменит и вообще сделает всё несовместимым.
 См. прикреплённый пример. |