C#TreeView有时会在无效后拒绝自己绘制

时间:2014-10-27 13:21:21

标签: c# treeview treenode

我使用TreeView在两个级别中显示一些信息:

  • A
    • 1
  • d
    • 1
    • 2
  • ...

有时,存储在树视图中的信息与显示的信息不同。这似乎是因为Paint()之后没有调用Invalidates()

我已经尝试过回答这个问题:C# Treeview doesn't refresh after moving nodes,但没有成功。

树(重新)创建代码:

using System.Windows.Forms.TreeNode;
using System.Windows.Forms.TreeView;
[...]
private void createTree()
{
    [...]// Creation code
    // Check update of the treeview
    foreach (TreeNode n in viewDataTreeView.Nodes) 
    {
        Console.WriteLine(n.Name);
        foreach (TreeNode child in n.Nodes)
        {
            Console.WriteLine("   " + child.Name);
        }
    }
    Console.WriteLine("done");
    this.Invalidate(true);
}

总是输出树视图中的正确树。有时,新添加的节点不会显示在屏幕上。

工作案例:

enter image description here

调用堆栈: enter image description here

工作callstack的功能:

private void toolStripDeleteTemplateButton_Click(object sender, EventArgs e)
{
    //Some confirmation stuff
    [...]
    // Delete the template file
    GraphTemplateNode node = this.viewDataTreeView.SelectedNode as GraphTemplateNode;
    File.Delete(node.GetTemplateFilePath());

    createTree();
}

不工作案例:

enter image description here

调用堆栈: enter image description here

请参阅Test 4缺失。

unworking callstack的功能:

//LineGraphUIControl.cs
private void saveTemplateToolStripButton_Click(object sender, EventArgs e)
{
    base.SaveGraphTemplate(lineGraphControl1.Graph);
}

//GraphUIControl.cs
public void SaveGraphTemplate(Graph graph)
{
    //Getting file name
    [...]
    //Creating template
    ViewDataSubControl.AddNewUserTemplate(tmplt);
}

// ViewDataSubControl.cs
public void AddNewUserTemplate(GraphTemplate tmplt)
{
    //Some string calculations
    [...]
    tmplt.SaveTemplate(fullName);
    createTree();
}

我尝试使用方法Refresh()Update()BeginUpdate() & EndUpdate()但没有运气。事件Invalidated总是被触发,但每次都无法调用Paint()。如果我强制调用InvokePaint(),TreeView也不会更新。

我能做些什么让它有效?

1 个答案:

答案 0 :(得分:3)

这个问题很不寻常,我怀疑渲染TreeView的逻辑是错误的。您在评论中写道,代码很长,您没有创建它而且您不想复制/粘贴它。

我理解这一点。

一般来说,有很多原因可以解决:

  • 某些时候可能缺少EndUpdate。检查删除并重新添加节点时运行的代码。

  • 节点显示定制可能很麻烦。检查可能对节点呈现产生影响的任何代码(例如DrawNode事件)

  • 检查异常处理程序。可能会发生异常并破坏代码流。如果适用,请删除空的catch部分。

  • 可能会滥用像this one这样的技巧,根据需要禁用重绘以加快显示速度。在最后一种情况下,丢失的ResumeDrawing可能会以同样的方式锁定它。

不幸的是,如果没有整个代码,很难猜到出了什么问题...所以我能做的最好的事情就是提供一些建议来检查它是什么:

  • 首先,对每个BeginUpdateEndUpdateSuspendDrawingResumeDrawing进行评论,然后检查会发生什么。

  • 如果错误仍然存​​在,请通过注释与其无关的内容,使代码尽可能简单地填充TreeView,禁用用于自定义节点显示的事件,如DrawNode事件(如果适用)

......直到它按预期工作。

  • 然后,取消注释代码片段,逐个重新启用现有功能,直到您遇到问题或通过查看代码注意到错误。你会以这种方式隔离bug。

希望它至少有一点帮助。