В пользовательской древовидной форме при рисовании узлов между узлами возникают некоторые артефакты. как убрать этот артC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 В пользовательской древовидной форме при рисовании узлов между узлами возникают некоторые артефакты. как убрать этот арт

Сообщение Anonymous »

Не могу понять, почему появляются эти артефакты и как их убрать?
вверху:
public partial class CustomFolderBrowser : Form
{
private TreeView folderTreeView;
private Button okButton;
private Button cancelButton;
private Button makeNewFolderButton;
private BufferedLabel feedbackLabel;

private Image expandIcon;
private Image collapseIcon;

public string SelectedPath { get; private set; }

затем в событии drawode:
private void FolderTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
// Get the bounds of the node
Rectangle nodeRect = e.Node.Bounds;

// Clear the icon area before redrawing
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); // Clear previous drawing

/*--------- 1. Draw expand/collapse icon ---------*/
if (e.Node.Nodes.Count > 0)
{
// Calculate position for expand/collapse icon
Point ptExpand = new Point(nodeRect.Left - 16, nodeRect.Top + (nodeRect.Height - 16) / 2); // Align vertically

// Choose the appropriate icon
Image expandCollapseImg = e.Node.IsExpanded ? collapseIcon : expandIcon;

// Draw the icon (ensure it is redrawn over a clear background)
e.Graphics.DrawImage(expandCollapseImg, ptExpand);
}

/*--------- 2. Draw node text ---------*/
// Get the node's font (default if none is set)
Font nodeFont = e.Node.NodeFont ?? ((TreeView)sender).Font;

// Set the color for the text (highlight if selected)
Brush textBrush = SystemBrushes.WindowText;
if ((e.State & TreeNodeStates.Selected) != 0)
{
textBrush = SystemBrushes.HighlightText;
e.Graphics.FillRectangle(SystemBrushes.Highlight, nodeRect); // Highlight background
}

// Draw the text
e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, nodeRect);

// Draw focus rectangle if node is selected
if ((e.State & TreeNodeStates.Focused) != 0)
{
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds);
}
}

этот артефакт возникает во многих узлах. я просто показываю несколько примеров.
Изображение

и здесь я отметил артефакты справа красными кружками
Изображение

вот полный код. немного длинноват, поэтому я положил его внизу.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace CustomFolder
{
public partial class CustomFolderBrowser : Form
{
private TreeView folderTreeView;
private Button okButton;
private Button cancelButton;
private Button makeNewFolderButton;
private BufferedLabel feedbackLabel;

private Image expandIcon;
private Image collapseIcon;

public string SelectedPath { get; private set; }

public CustomFolderBrowser()
{
InitializeComponents();

okButton.Enabled = false;
this.StartPosition = FormStartPosition.CenterScreen;

// Load the icons from resources (make sure these are 16x16 size)
expandIcon = Properties.Resources.icons8_forward_8; // Right-facing arrow
collapseIcon = Properties.Resources.icons8_expand_arrow_8; // Down-facing arrow

// Enable owner drawing for the TreeView
folderTreeView.DrawMode = TreeViewDrawMode.OwnerDrawAll;
folderTreeView.DrawNode += FolderTreeView_DrawNode;

this.Resize += CustomFolderBrowser_Resize;
this.Move += CustomFolderBrowser_Move;

LoadDrives();
}

private void CustomFolderBrowser_Move(object sender, EventArgs e)
{
UpdateFeedbackLabel();
}

private void CustomFolderBrowser_Resize(object sender, EventArgs e)
{
UpdateFeedbackLabel();
}

private void UpdateFeedbackLabel()
{
// Code to update move and resize feedback, if necessary
}

private void InitializeComponents()
{
this.Text = "Select Folder";
this.Size = new Size(332, 349);

folderTreeView = new DoubleBufferedTreeView
{
Size = new Size(290, 208),
Location = new Point(12, 55)
};

folderTreeView.AfterSelect += FolderTreeView_AfterSelect;
folderTreeView.BeforeExpand += FolderTreeView_BeforeExpand;

okButton = new Button
{
Text = "Ok",
Size = new Size(75, 23),
Location = new Point(147, 280)
};
okButton.Click += OkButton_Click;

cancelButton = new Button
{
Text = "Cancel",
Size = new Size(75, 23),
Location = new Point(227, 280)
};
cancelButton.Click += (s, e) => this.Close();

makeNewFolderButton = new Button
{
Text = "Make New Folder",
Size = new Size(120, 23),
Location = new Point(12, 280)
};

feedbackLabel = new BufferedLabel
{
Text = string.Empty,
ForeColor = Color.Red,
Size = new Size(300, 20),
Location = new Point(12, 25)
};

Controls.Add(folderTreeView);
Controls.Add(feedbackLabel);
Controls.Add(okButton);
Controls.Add(cancelButton);
Controls.Add(makeNewFolderButton);
}

private void LoadDrives()
{
foreach (var drive in DriveInfo.GetDrives())
{
TreeNode node = new TreeNode(drive.Name) { Tag = drive.RootDirectory.FullName };
folderTreeView.Nodes.Add(node);
node.Nodes.Add("Loading..."); // Placeholder for expandable drives
}

feedbackLabel.Select();
}

private void FolderTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
TreeNode node = e.Node;
if (node.Nodes[0].Text == "Loading...")
{
node.Nodes.Clear();
LoadSubDirectories(node);
}
}

private void LoadSubDirectories(TreeNode node)
{
string path = (string)node.Tag;
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(path);
foreach (var directory in directoryInfo.GetDirectories())
{
TreeNode subNode = new TreeNode(directory.Name) { Tag = directory.FullName };
node.Nodes.Add(subNode);
subNode.Nodes.Add("Loading...");
okButton.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
feedbackLabel.Text = "Access Denied to folder.";
okButton.Enabled = false;
}
}

private void FolderTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
string selectedPath = (string)e.Node.Tag;
DirectoryInfo directoryInfo = new DirectoryInfo(selectedPath);
try
{
var subDirs = directoryInfo.GetDirectories();
feedbackLabel.Text = string.Empty;
SelectedPath = selectedPath;
okButton.Enabled = true;
}
catch (UnauthorizedAccessException)
{
feedbackLabel.Text = "Folder Access Denied.";
okButton.Enabled = false;
}
}

private void FolderTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
// Get the bounds of the node
Rectangle nodeRect = e.Node.Bounds;

// Clear the icon area before redrawing
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); // Clear previous drawing

/*--------- 1. Draw expand/collapse icon ---------*/
if (e.Node.Nodes.Count > 0)
{
// Calculate position for expand/collapse icon
Point ptExpand = new Point(nodeRect.Left - 16, nodeRect.Top + (nodeRect.Height - 16) / 2); // Align vertically

// Choose the appropriate icon
Image expandCollapseImg = e.Node.IsExpanded ? collapseIcon : expandIcon;

// Draw the icon (ensure it is redrawn over a clear background)
e.Graphics.DrawImage(expandCollapseImg, ptExpand);
}

/*--------- 2. Draw node text ---------*/
// Get the node's font (default if none is set)
Font nodeFont = e.Node.NodeFont ?? ((TreeView)sender).Font;

// Set the color for the text (highlight if selected)
Brush textBrush = SystemBrushes.WindowText;
if ((e.State & TreeNodeStates.Selected) != 0)
{
textBrush = SystemBrushes.HighlightText;
e.Graphics.FillRectangle(SystemBrushes.Highlight, nodeRect); // Highlight background
}

// Draw the text
e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, nodeRect);

// Draw focus rectangle if node is selected
if ((e.State & TreeNodeStates.Focused) != 0)
{
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds);
}
}

private void OkButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(SelectedPath))
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}

private void UpdateTreeView()
{
folderTreeView.BeginUpdate();
try
{
// Perform updates to the TreeView here
}
finally
{
folderTreeView.EndUpdate();
}
}

public class BufferedLabel : Label
{
public BufferedLabel()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
}
}

public class DoubleBufferedTreeView : TreeView
{
public DoubleBufferedTreeView()
{
// Enable double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.UpdateStyles();
}

protected override void WndProc(ref Message m)
{
// Suppress background erase to reduce flickering
if (m.Msg == 0x0014) // WM_ERASEBKGND
return;

base.WndProc(ref m);
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... cts-betwee
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»