0

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:

enter image description here

callstack: enter image description here

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:

enter image description here

callstack: enter image description here

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 ?

Community
  • 1
  • 1
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
  • 1
    Some screenshots and details (winforms/wpf, code for updating, threading?) would be ace! – Sinatr Oct 27 '14 at 13:23
  • About how often is 'sometimes', meaning: Is it anything close to reproducible? – TaW Oct 27 '14 at 14:09
  • @TaW I just find out how to reproduce (on my computer). If I delete a node, it's displayed well, if I add a node, it won't display itself. The callstack is the same (deletion call recreateTree() ) – Thomas Ayoub Oct 27 '14 at 14:11
  • Hm, where and how do you add those nodes? Is it in this constructor: `new GraphUINode(this, graphUIName);` – TaW Oct 27 '14 at 14:45
  • @TaW yes it is. In graphUiNode I use `viewDataSubControl.viewDataTreeView.Nodes.Add(this);` viewDataSubControl being `this` in the constructor call – Thomas Ayoub Oct 27 '14 at 14:48
  • @Thomas did you try using ```TreeView.BeginUpdate()``` and ```TreeView.EndUpdate()``` methods to surround your code modifying the tree storage ? Try using refresh and update with the Update method to see if there is some differences. – Maxime Mangel Oct 27 '14 at 14:55
  • @MaximeMangel (you don't need to `@` the OP when commenting the question) It doesn't work either... – Thomas Ayoub Oct 27 '14 at 15:03
  • How exectly do you code the class? (It is a class right? You can't access an outer element without extra code, after all..) – TaW Oct 27 '14 at 15:05
  • @TaW Yes it's a class. I'm new in the project and I didn't code it by myself. I can't copy/paste hundred lines of code, it would make no sense. I don't know how I can help you to help me... – Thomas Ayoub Oct 27 '14 at 15:09
  • That's right. Are all nodes added in the constructor? Does the display miss all nodes added later? Or only those you first remove and re-add? – TaW Oct 27 '14 at 15:15
  • @TaW No matter how many node I add, it'll not be displayed. Unless I restart the application OR delete one displayed node. – Thomas Ayoub Oct 27 '14 at 15:17
  • Just a wild guess (not more I can do as it is..) since all nodes you add are objects and each object can only be added once, unless you remove it and then re-add it, maybe somewhere else, could it be that the adding fails silently inside a try-catch routine? (But that doesn't fit with the console test output..) Did you mean 'delete one or any one node'? – TaW Oct 27 '14 at 15:24
  • To extands last answer of @TaW I remember that someone speaking about this problem that you can only have one instance of a classes in a tree view. So he speaks of using clone. Can't find that post... – Maxime Mangel Oct 27 '14 at 15:26
  • @TaW no try/catch routine, I made a step by step debug and found nothing like so... I meant `delete a node which is displayed on the screen`. To fit with the second screengrab, delete Test8 will delete it from the display and add Test4. – Thomas Ayoub Oct 27 '14 at 15:27
  • @MaximeMangel I tested it (also see the Q/A) but it was not working either. – Thomas Ayoub Oct 27 '14 at 15:28
  • Shrug. This is weird non-standard behaviour. In such a case I would either seek help from the folks who have coded the node and possibly the treview class; if that is not an option I would try to re-create with a standard treeview.. – TaW Oct 27 '14 at 15:31
  • In my own test I had to create two node constructors, one normal and one for adding later, into which I handed the treeview; did they do it simlarily? – TaW Oct 27 '14 at 15:32
  • @TaW they did just one, but everytime they erase the whole treeview and start from the beginning – Thomas Ayoub Oct 27 '14 at 15:34
  • Please search for ".IsVisible" in the solution. This property triggers a node visibility. Probably some logic is hidden somewhere in other parts of the code? – Larry Oct 29 '14 at 13:57
  • @Larry I've already done this, all node are "visible". Even the ones I don't see. I order to be sure I try to add a number to the node text and even the number is not visible. So it's not the issue... – Thomas Ayoub Oct 29 '14 at 13:59

1 Answers1

3

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.

Community
  • 1
  • 1
Larry
  • 17,605
  • 9
  • 77
  • 106
  • I updated the question with callstack and more code. I'll try all you said in your anwser (which is nice btw) – Thomas Ayoub Oct 30 '14 at 08:07
  • Oh I see: it's a custom corporate TreeView. I do know Sakura.UI.Graphing.dll as it does not seems to be an opensource graphic library (At least as far I know... If it is, please post a link). That's why I am afraid the stacktrace and the code wont help here, because I dont know the non-standard functions that composes this library. I suggest you to dig a bit deeper inside this library and check the code that hit the inner standard .net TreeView hidden behind. Good luck! – Larry Oct 30 '14 at 08:35
  • Let's have a talk here (FR ;)) it could be easier to deal with it: http://chat.stackoverflow.com/rooms/63914/larrys-room – Larry Oct 30 '14 at 08:41