C# TreeView 有时会在失效后拒绝绘制自己 [英] C# TreeView sometimes refuse to paint itself after invalidates

查看:22
本文介绍了C# TreeView 有时会在失效后拒绝绘制自己的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  • A
    • 1
  • D
    • 1
    • 2
  • ...

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

我已经尝试过这个问题的答案: 禁用按需重绘以加快显示速度.在最后一种情况下,丢失的 ResumeDrawing 可以用同样的方式锁定它.

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

  • 首先,将每个BeginUpdateEndUpdateSuspendDrawingResumeDrawing 一起注释,并检查会发生什么.

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

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

  • 然后,取消注释代码段以重新启用现有功能,一个接一个,直到您发现问题或通过查看代码发现问题所在.您将通过这种方式隔离错误.

希望它至少有所帮助.

I use a TreeView to display some informations in two levels :

  • A
  • B
    • 1
  • D
    • 1
    • 2
  • ...

Sometimes, the informations stored in the treeview differs with the one displayed. It seems that it's because Paint() is not called after Invalidates().

I already tried answer from this question : C# Treeview doesn't refresh after moving nodes, without success.

Tree (re)Creation code :

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);
}

Which always output the correct tree that I have in the treeview. And sometimes, newly added node are not displayed on the screen.

Working case:

callstack:

Functions of working 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();
}

Not working case:

callstack:

See the Test 4 is missing.

Functions of 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();
}

I tried to use the method Refresh(), Update() and BeginUpdate() & EndUpdate() with no luck. The event Invalidated is always fired, but I can't get Paint() to be called everytime. If I force call with InvokePaint() the TreeView is not updated either.

What can I do to make it works ?

解决方案

That issue is unusual, and I suspect that it is something wrong in the logic that renders the TreeView. You wrote in a comment that the code is long, you did not create it and you don't want to copy/paste it.

I understand this.

In general, there are many reasons why it could happen:

  • It might be a missing EndUpdate at some point. Check the code that runs when you delete and re-add a node.

  • Node display customization can be troublesome. Check any code that could have an impact on node rendering (the DrawNode event for example)

  • Check exception handlers. An exception could happens and break a code flow. Remove empty catch sections if it applies.

  • It might be a misuse of a trick like this one that disable Redraws on demand to speed up the display. In this last case, a missing ResumeDrawing could lock it the same way.

Unfortunately it is very hard to guess what is wrong without the whole code... So the best I can do to help is to give some advices to check what it is going on:

  • At first, comment every BeginUpdate, EndUpdate, SuspendDrawing, ResumeDrawing together, and check what happens.

  • If the bug is still here, have a code that populates the TreeView as simple as possible by commenting what is not related to it, Disable events that are used to customize the node display like the DrawNode event (if it applies)

...until it works as expected.

  • Then, uncomment pieces of codes to re-enable existing features, one by one, until you bump on the issue or notice what is wrong by looking at the code. You will isolate the bug this way.

Hope it helps at least a bit.

这篇关于C# TreeView 有时会在失效后拒绝绘制自己的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆